本文为CP根据网上内容以及U-Boot 2014.4版本进行整理而成。
原文地址为 http://blog.chinaunix.net/uid-8867796-id-358806.html———————————————————————————————————————————————————
1:uboot的命令解析执行代码在main_loop()函数中实现,其向上的调用层次是:main_loop()//common\Main.cßboard_init_r()//arch\arm\lib\board.cßctr0.S//arch\arm\libßstart.S//arch\arm\cpu\arm7.
2. 现在我们已经进入了这个圈套那么只能往里钻了. common/main.c文件中的main_loop().
Main_loop会进入process_boot_delay()来处理boot延时。在process_boot_delay()内有如下操作: // 宏定义CONFIG_BOOTCOUNT_LIMIT猜测是限制启动次数的功能 #ifdef CONFIG_BOOTCOUNT_LIMIT bootcount = bootcount_load();
//从环境变量里找bootdelay //获取bootcmd 以作为默认启动参数开始启动 run_command_list(s, -1, 0); |
上面代码主要是对自启动部分的描述, 其中命令执行部分是在run_command中进行的, 这个等在后文分析. 如果我们没有bootcmd或者在延时中被打断, 那么代码会继续向下执行
//下面for循环是uboot处理终端命令的主循环, 这时等待我们从键盘中输入一行命令, 真正的人机交互从这里开始 |
3.read_line()读取到命令行后会调用common/main.c文件中的run_command(). 现在是分析run_command()的时候了, 不管是从环境变量还是终端获得命令, 都是由run_command()来处理的.
run_command()函数实际执行的是 builtin_run_command(cmd, flag)函数 //下面if语句判断命令是否太长, 还是避免有些变态的家伙输入了超过CFG_CBSIZE个字符的命令 |
//str就是指向cmdbuf的指针, 其实这些东西都是针对的刚才那行命令 /* |
//先研究一下这个神奇的U_BOOT_CMD, 定义如下, 其中cmd_tbl_t是命令的结构体类型, 这里不罗列了,成员包括命令名字, 参数的最大个数, 使用说明等等. U_BOOT_CMD定义为 #define U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, \ _usage, _help, _comp) \ { #_name, _maxargs, _rep, _cmd, _usage, \ _CMD_HELP(_help) _CMD_COMPLETE(_comp) } #define U_BOOT_CMD_MKENT(_name, _maxargs, _rep, _cmd, _usage, _help) \ U_BOOT_CMD_MKENT_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(_name, _maxargs, _rep, _cmd, _usage, _help) \ U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, NULL) cmd_tbl_t *find_cmd (const char *cmd)函数会找到命令区的入口以及命令总数,并最终调用 cmd_tbl_t *find_cmd_tbl (const char *cmd, cmd_tbl_t *table, int table_len) 找到指定命令的入口 |
5. 刚才我们在长征的半路翻越了一座雪山, 现在继续回到while循环中