uboot命令的U_BOOT_CMD

来源:互联网 发布:人工智能软件小冰下载 编辑:程序博客网 时间:2024/06/05 14:08

版本uboot2014.1


    U_BOOT_CMD是一个宏定义,具体功能是定义一个struct cmd_tbl_s的结构体变量,U_BOOT_CMD宏传递的参数是该结构体变量的成员变量。通过U_BOOT_CMD定义的变量会通过脚本链接到uboot指定的一个section中,然后可以通过find_cmd遍历这个section找到这个cmd,可以通过run_command(cmd, flag)函数执行具体命令。


    uboot的命令都存放在uboot/common/目录下,可以在该目录下的Makefile中添加编译命令的选项。如,网络的编译选项如下:

obj-$(CONFIG_CMD_NET) += cmd_net.o

    网络的具体命令是再uboot/common/cmd_net.c中定义的,如nfs命令

#if defined(CONFIG_CMD_NFS)static int do_nfs(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]){return netboot_common(NFS, cmdtp, argc, argv);}U_BOOT_CMD(nfs,3,0,do_nfs,"boot image via network using NFS protocol","[loadAddress] [[hostIPaddr:]bootfilename]");#endif

可以看出nfs命令是通过U_BOOT_CMD宏定义“注册“的,并关联上do_nfs(...)函数,执行具体功能。这里的U_BOOT_CMD是在uboot/include/command.h文件中定义的,如下:

#define U_BOOT_CMD(_name, _maxargs, _rep, _cmd, _usage, _help)\U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, NULL)

U_BOOT_CMD_COMPLETE定义紧挨着,如下:

#define U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, _comp) \ll_entry_declare(cmd_tbl_t, _name, cmd) =\U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd,\_usage, _help, _comp);

这里可以看出是一个赋值语句(其实“=”前面是定义一个变量,后面赋值)。“=”后面的宏定义紧挨着,如下:

#define U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd,\_usage, _help, _comp)\{ #_name, _maxargs, _rep, _cmd, _usage,\_CMD_HELP(_help) _CMD_COMPLETE(_comp) }
注:这里的“#”,作用是将_name传递的值字符串化。_CMD_HELP和_CMD_COMPLETE就是取本身(具体宏定义在本文件command.h中)。
可以看出,这个宏定义的作用就是将U_BOOT_CMD传递的参数放在大括号内。


“=”前面的ll_entry_declare也是一个宏定义,具体在uboot/include/linker_lists.h中,如下

#define ll_entry_declare(_type, _name, _list)\_type _u_boot_list_2_##_list##_2_##_name __aligned(4)\__attribute__((unused,\section(".u_boot_list_2_"#_list"_2_"#_name)))

注:这里的"##"表示连接作用。即##_list##表示用_list变量的值替换当前位置。

即通过_type传递变量类型,_name和_list传递组成变量名称的字符串,然后将该变量放在section中,section的名称也由_name和_list命令传递。这里的__aligned(4)是指定定义的变量4字节对其,__attribute是选择未使用的section,可以在理解原理时忽略掉。


这里的_type=cmd_tbl_t,后者的定义如下:

typedef struct cmd_tbl_scmd_tbl_t;
即cmd_tbl_t就是cmd_tbl_s,定义如下:

struct cmd_tbl_s {char*name;/* Command Name*/intmaxargs;/* maximum number of arguments*/intrepeatable;/* autorepeat allowed?*//* Implementation function*/int(*cmd)(struct cmd_tbl_s *, int, int, char * const []);char*usage;/* Usage message(short)*/#ifdefCONFIG_SYS_LONGHELPchar*help;/* Help  message(long)*/#endif#ifdef CONFIG_AUTO_COMPLETE/* do auto completion on the arguments */int(*complete)(int argc, char * const argv[], char last_char, int maxv, char *cmdv[]);#endif};

如前所述,U_BOOT_CMD的作用就是定义一个结构体变量(struct cmd_tbl_s),并将其存放再uboot的没有被占用的section中。展开就是:

struct cmd_tbl_s _u_boot_list_2_cmd_2_##_name = {#_name, _maxargs, _rep, _cmd, _usage, _help, NULL};
注:该变量属性是4字节对齐(__aligned(4) ),存放在未被使用的section中,并将该section命名为【".u_boot_list_2_"#name】(__attribute__((unused, section(".u_boot_list_2_"#name))))。


举例:

------------------------------------------------------

命令nfs

U_BOOT_CMD(nfs,3,0,do_nfs,"boot image via network using NFS protocol","[loadAddress] [[hostIPaddr:]bootfilename]");

即为:

struct cmd_tbl_s _u_boot_list_2_cmd_2_nfs = {"nfs", 3, 0, do_nfs,"boot image via network using NFS protocol","[loadAddress] [[hostIPaddr:]bootfilename]", NULL};

将_u_boot_list_2_cmd_2_nfs变量4字节对齐存放在未被使用的uboot的section中,该section被命名为.u_boot_list_2_nfs。










0 0
原创粉丝点击