以 2013.04 u-boot为例
1. 通过 U_BOOT_CMD 定义一个类型为 cmd_tbl 的变量,而 cmd_tbl 的成员就是宏函数 U_BOOT_CMD 的参数
2. 所有通过U_BOOT_CMD 定义的变量,都通过脚本链接到 uboot.bin 的一个 section 中
3. 使用函数 find_cmd 遍历整个 section,找到 cmd
在 u-boot 中,命令的实现代码都是在目录 \common 下,命令的添加是通过宏函数 U_BOOT_CMD 实现的。而 U_BOOT_CMD 的定义是在目录 \include 下
#define U_BOOT_CMD(_name, _maxargs, _rep, _cmd, _usage, _help) \
U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, NULL)
#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) }
ll_entry_declare 也是一个宏函数,定义也是目录 \include 下的文件 link_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)))
比如说,命令 bootz 的定义是在文件 cmd_bootm.c 中,我们就以这个为例讲一下。
U_BOOT_CMD(
bootz, CONFIG_SYS_MAXARGS, 1, do_bootz,
"boot Linux zImage image from memory", bootz_help_text
);
根据以上给出的宏定义展开之后得到
ll_entry_declare(cmd_tbl_t, bootz, cmd) = \
U_BOOT_CMD_MKENT_COMPLETE(bootz, CONFIG_SYS_MAXARGS, 1, do_bootz, \
"boot Linux zImage image from memory", bootz_help_text, NULL);
进一步展开(关于"##name的用法大家可以网上查")
cmd_tbl_t _u_boot_list_2_cmd_2_bootz __aligned(4) \ __attribute__((unused, section(".u_boot_list_2_"#_list"_2_"#_name))) = \
{bootz, CONFIG_SYS_MAXARGS, 1, do_bootz, "boot Linux zImage image from memory", bootz_help_text, NULL}
_aligned(4) 和 _attribute_(……) 是修饰变量 _u_boot_list_2_cmd_2_bootz 的,这个不是我们讨论的重点,暂且忽略它。那这样的话,可以写成这样
我们再来看看结构体 cmd_tbl_t 的定义: typedef struct cmd_tbl_s cmd_tbl_tcmd_tbl_t _u_boot_list_2_cmd_2_bootz = \ {bootz, CONFIG_SYS_MAXARGS, 1, do_bootz, "boot Linux zImage image from memory", bootz_help_text, NULL}
刚好和上式的内容相符,只是最后一个成员的值为 "NULL"。struct cmd_tbl_s { char *name; /* Command Name */ int maxargs; /* maximum number of arguments */ int repeatable; /* autorepeat allowed? */ /* Implementation function */ int (*cmd)(struct cmd_tbl_s *, int, int, char * const []); char *usage; /* Usage message (short) */ #ifdef CONFIG_SYS_LONGHELP char *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 };