博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
uboot执行顺序main_loop
阅读量:4283 次
发布时间:2019-05-27

本文共 3215 字,大约阅读时间需要 10 分钟。

前言
uboot 如果最后走到了用户交互模式,则会循环在 main_loop 函数(位于common/main.c,main.c中的出口函数) 中main_loop 被 start_armboot 函数调用

main_loop 流程

  • 全部流程
会解析bootdelay变量,并延时	在延时中如果被中断,则会执行一个循环,循环中readline并执行 run_command  	如果没被中断,会解析变量boot_cmd里面的变量,并执行run_command  	1/判断了长度  	2/依据;截取字符串,得到一个一个的命令    3/去掉宏,得到一个解析过的命令    4/分析一个命令得到 命令名 和 参数    5/依次将 命令名 和	结构体数组 中的结构体成员的第一个参数 name 进行比较,判断是否相等.相等说明是合法命令    6/判断合法命令的 参数个数 是否合法    7/调用命令在上述序列中, 步骤 5 最难理解

命令及命令集的遍历解析

  • 结构体类型
typedef struct cmd_tbl_s	cmd_tbl_t;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 CONFIG_SYS_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};
  • 结构体数组
其实步骤5中的结构体数组并没有在程序中定义.而是依靠段的用法将这些结构体存到了指定的段中,然后在链接的时候将各个文件的这个段 连接到一个输出文件的 段中,也就是将这些结构体放到了一起,所以就像我之前说的结构体数组.下面分为两个部分说1/输入文件中的段    它是用宏函数 U_BOOT_CMD(name,maxargs,rep,cmd,usage,help),宏函数的定义在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}          bootm 解析        假设这个命令是bootm ,U_BOOT_CMD(bootm, 16, 1, do_bootm, “bootm--usage”, “help”)      最后展开会成为这个样子    cmd_tbl_t  __u_boot_cmd_ bootm  __attribute__ ((unused,section (".u_boot_cmd"))) = {
“bootm”, 16, 1, do_bootm, “bootm--usage”} 表示 定义一个结构体 变量 类型为 cmd_tbl_t 初始化为{
“bootm”, 16, 1, do_bootm, “bootm--usage”} 变量地址 在 段名 ".u_boot_cmd" 中,而到底在段中的什么位置,依赖于链接顺序 2/输出文件中的段 链接的时候会读取链接文件include/u-boot/u-boot.lds 按照链接顺序 依次 将输入文件中的 ".u_boot_cmd" 段 放入 输出文件中的 ".u_boot_cmd" 段 __u_boot_cmd_start = .; .u_boot_cmd : {
*(.u_boot_cmd) } __u_boot_cmd_end = .; .u_boot_cmd段开始的位置符号为 __u_boot_cmd_start ,段结束地址符号为 __u_boot_cmd_end
  • 结构体数组的遍历
main_loop    readline        run_command  // 如果 command 是 "bootm 0x30008000"            判断了长度,截取字符串,将宏去掉,得到 "bootm"            cmtp = find_cmd(); // 根据字符串"bootm" 对比 命令中的name成员 找到命令            cmdtp->cmd //找到命令
cmd_tbl_t *find_cmd (const char *cmd){
int len = &__u_boot_cmd_end - &__u_boot_cmd_start; return find_cmd_tbl(cmd, &__u_boot_cmd_start, len);}cmd_tbl_t *find_cmd_tbl (const char *cmd, cmd_tbl_t *table, int table_len){
cmd_tbl_t *cmdtp; cmd_tbl_t *cmdtp_temp = table; /*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 = table; cmdtp != table + table_len; 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 */} ----并执行if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) {
rc = -1;}

转载地址:http://ntigi.baihongyu.com/

你可能感兴趣的文章
JavaScript+IndexedDB实现留言板:客户端存储数据
查看>>
问题:如何在固定大小的DIV层插入N多个图片
查看>>
怎么解决div覆盖内容却没覆盖的问题?
查看>>
九个Console命令,让js调试更简单
查看>>
Linux与Windows的8个不同
查看>>
如何给超链接设置宽度和高度
查看>>
趣文:你对程序员适不适合做老公的看法是?
查看>>
仿照某商城首页的源代码及效果
查看>>
网络大牛如何回答Chrome的15个刁钻面试题?
查看>>
某网站静态首页的实现小结
查看>>
常用的正则表达式归纳—JavaScript正则表达式
查看>>
jq实现图片轮播:圆形焦点+左右控制+自动轮播
查看>>
问题:关于贴友分类菜单的实现
查看>>
PHP图像操作:3D图、缩放、旋转、裁剪、添加水印(二)
查看>>
PHP图像操作:3D图、缩放、旋转、裁剪、添加水印(三)
查看>>
document.body、document.documentElement和window获取视窗大小的区别
查看>>
教你利用iframe在网页中显示天气
查看>>
利用Javascript获取当前日期的农历日期
查看>>
利用原生JavaScript获取样式的方式小结
查看>>
PHP制作验证码
查看>>