三、uboot_命令实现

一、uboot命令实现

1、run_commond(commom/main.c)

int run_command (const char *cmd, int flag)
{
    while (*str) {

		/*
		 * Find separator, or string end
		 * Allow simple escape of ';' by writing "\;"
		 */
1、使用分号将命令提取出来
		for (inquotes = 0, sep = str; *sep; sep++) {
			if ((*sep=='\'') &&
			    (*(sep-1) != '\\'))
				inquotes=!inquotes;

			if (!inquotes &&
			    (*sep == ';') &&	/* separator		*/
			    ( sep != str) &&	/* past string start	*/
			    (*(sep-1) != '\\'))	/* and NOT escaped	*/
				break;
		}
2、处理宏(环境变量等)
/* find macros in this token and replace them */
		process_macros (token, finaltoken);
    
3、解析命令参数,保存在argv字符串数组
/* Extract arguments */
		if ((argc = parse_line (finaltoken, argv)) == 0) {
			rc = -1;	/* no command at all */
			continue;
		}
4、查找命令
/* Look up command in command table */
		if ((cmdtp = find_cmd(argv[0])) == NULL) {
			printf ("Unknown command '%s' - try 'help'\n", argv[0]);
			rc = -1;	/* give up after bad command */
			continue;
		}

}

2、命令查找函数 

cmd_tbl_t *find_cmd (const char *cmd)
{
	cmd_tbl_t *cmdtp;
	cmd_tbl_t *cmdtp_temp = &__u_boot_cmd_start;	/*Init value */
	const char *p;
	int len;
	int n_found = 0;

	/*
	 * Some commands allow length modifiers (like "cp.b");
	 * compare command name only until first dot.
	 */
	len = ((p = strchr(cmd, '.')) == NULL) ? strlen (cmd) : (p - cmd);

	for (cmdtp = &__u_boot_cmd_start;
	     cmdtp != &__u_boot_cmd_end;
	     cmdtp++) {
		if (strncmp (cmd, cmdtp->name, len) == 0) {
			if (len == strlen (cmdtp->name))
				return cmdtp;	/* full match */

			cmdtp_temp = cmdtp;	/* abbreviated command ? */
			n_found++;
		}
	}
	if (n_found == 1) {			/* exactly one match */
		return cmdtp_temp;
	}

	return NULL;	/* not found or ambiguous command */
}


__u_boot_cmd_start和__u_boot_cmd_end之间的命令保存在链接脚本

	__u_boot_cmd_start = .;
	.u_boot_cmd : { *(.u_boot_cmd) }
	__u_boot_cmd_end = .;

3、命令实现原理

1、以bootm为例,说明命令实现过程
U_BOOT_CMD(
 	bootm,	CFG_MAXARGS,	1,	do_bootm,
 	"bootm   - boot application image from memory\n",
 	"[addr [arg ...]]\n    - boot application image stored in memory\n"
 	"\tpassing arguments 'arg ...'; when booting a Linux kernel,\n"
 	"\t'arg' can be the address of an initrd image\n"
#ifdef CONFIG_OF_FLAT_TREE
	"\tWhen booting a Linux kernel which requires a flat device-tree\n"
	"\ta third argument is required which is the address of the of the\n"
	"\tdevice-tree blob. To boot that kernel without an initrd image,\n"
	"\tuse a '-' for the second argument. If you do not pass a third\n"
	"\ta bd_info struct will be passed instead\n"
#endif
);

2、U_BOOT_CMD宏实现
<include/command.h>
#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \
cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage, help}

3、展开
cmd_tbl_t __u_boot_cmd_bootm Struct_Section = {"bootm", CFG_MAXARGS, 1, do_bootm, usage, help}

4、将Struct_Section展开
<include/command.h>
#define Struct_Section  __attribute__ ((unused,section (".u_boot_cmd")))
cmd_tbl_t __u_boot_cmd_bootm __attribute__ ((unused,section (".u_boot_cmd"))) = {"bootm", CFG_MAXARGS, 1, do_bootm, usage, help}

5、说明
创建一个cmd_tbl_t类型的__u_boot_cmd_bootm结构体,属性为保存在".u_boot_cmd"段(链接脚本会说明)的地址,成员为 {"bootm", CFG_MAXARGS, 1, do_bootm, usage, help}

4、实现一个命令(hello:打印一个hello)

(1)创建一个命令文件(common/cmd_hello.c)

#include <common.h>
#include <watchdog.h>
#include <command.h>
#include <image.h>
#include <malloc.h>
#include <zlib.h>
#include <bzlib.h>
#include <environment.h>
#include <asm/byteorder.h>

int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	int i=0;
	printf("hello world ! , %d\n", argc);
	for(;i<argc;i++)
	{
		printf("hello argv[%d] ->  %s\n", i, argv[i]);
	}
	return 0;
}

U_BOOT_CMD(
 	hello,	CFG_MAXARGS,	1,	do_hello,
 	"hello, -just for test\n",
 	"hello, long help ---------\n"
);

(2)将命令添加至uboot

1、在common目录下的Makefile中添加cmd_hello.h
OGJS = ....
    cmd_hello.o

猜你喜欢

转载自blog.csdn.net/liutit/article/details/127579057