Uboot的命令格式
在Uboot的doc目录下的README.commands文件说明如下:
U_BOOT_CMD(name,maxargs,repeatable,command,"usage","help")
name: is the name of the commad. THIS IS NOT a string.
maxargs: the maximumn numbers of arguments this function takes
command: Function pointer (*cmd)(struct cmd_tbl_s *, int, int, char *[]);
usage: Short description. This is a string
help: long description. This is a string
在include/command.h文件中定义如下:
// command的结构数据
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 *[]);
char *usage; /* Usage message (short) */
#ifdef CFG_LONGHELP
char *help; /* Help message (long) */
#endif
#ifdef CONFIG_AUTO_COMPLETE
/* do auto completion on the arguments */
int (*complete)(int argc, char *argv[], char last_char, int maxv, char *cmdv[]);
#endif
};
typedef struct cmd_tbl_s cmd_tbl_t; // 重新定义一个名字
// 定义Struct_Section, __attribute__ ((unused,section (".u_boot_cmd")))会将
// 使用该属性定义的数据放到.u_boot_cmd段中,
// 该段在board/psbec270/uboot.lds文件中有定义:
/*
…
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) } // 将这个.u_boot_cmd段的放在这里
__u_boot_cmd_end = .;
*/
#define Struct_Section __attribute__ ((unused,section (".u_boot_cmd")))
// 下面的这个宏广泛运用于整个系统中, 用于定义用户实现的命令, 初始化这样的
// 一条命令, 就将在.u_boot_cmd段中增加一段数据.
#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}
系统初始化后进入主循环mainloop(),首先检测bootdelay,如果有则读取环境变量bootdelay的值,等待bootdelay秒,如果用户在这个期间没有输入任何数据,那么执行用户定义的bootcmd中指定的命令。
s = getenv ("bootdelay"); // 得到环境变量指定的delay值
bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
s = getenv ("bootcmd"); // 得到自动启动命令
// 如果bootdelay的值是大于等于0, 并且abortboot (bootdelay)返回0, 那么就执行
// 自动启动
if (bootdelay >= 0 && s && !abortboot (bootdelay)) {
// abortboot()函数输出提示用户在指定时间内按下任意按键将停止自动运行,
// 然后等待用户输入, 如果bootdelay已经减到0, 并且用户还是没有输入,
// 函数将返回0, 否则返回1.
# ifdef CONFIG_AUTOBOOT_KEYED
int prev = disable_ctrlc(1); /* disable Control C checking */
# endif
// 运行用户预定义的自动启动命令
# ifndef CFG_HUSH_PARSER
run_command (s, 0);
# else
parse_string_outer(s, FLAG_PARSE_SEMICOLON |
FLAG_EXIT_FROM_LOOP);
# endif
# ifdef CONFIG_AUTOBOOT_KEYED
disable_ctrlc(prev); /* restore Control C checking */
# endif
}
如果执行上面的函数的时候用户按下了任意键,将继续执行到这里,mainloop输出一些提示符后会一直等等用户的输入,当用户输入完成后,对用户的输入进行解析,根据命令的不同到.u_boot_cmd中查找指定的命令,找到后执行对应的函数。
命令的解析方法有两种,第一种就是最笨的办法,直接到.u_boot_cmd段中进行字符串比较,找到相同的那么就执行,如果命令比较少,相对来说对性能没有太大的损失,但是当命令很多时这种方法就不是很合适了。Uboot使用另外一种查找办法解决这个问题:使用hush表,只要用户在configs/psbec270.h文件中定义:
#define CFG_HUSH_PARSER
就可以实现了。这种方法与上面的方法基本相同,只是在查找方式上做了优化,这样可以提高查找速度,具体的代码可以查看common/main.c文件。
(本文章发表于psbec的个人blog,未经本人许可,不得用于商业用途。任何个人、媒体、其他网站不得私自抄袭;网络媒体转载请注明出处,增加原文链接,否则属于侵权行为。如有任何问题,请留言或者发邮件给psbec,地址)
阅读(1607) | 评论(0) | 转发(0) |