笔记整理—uboot番外(1)命令体系

        在uboot启动进行命令行的环境下,当输入命令时,将会对命令进行先解析后执行的操作。

uboot/common/cmd_xxx.c    其中就有多个命令体系(mian.c和commann.c)

        uboot每个命令都对应了一个相关的函数,由此实现的命令体系与shell的方式相似。其中参数一int类型的argc与char*argv[]组成。命令+参数,在Linux体系中,之类也是算作argc中的一员。

eg:
help ping
argc=2;
argv[0]="help";
argv[1]="ping";

        相关的代码为int do_help(cmd_tbl_t *cmdtp,intflag,intargc,char *argv[]);

        

        mian_loop的函数命令解析过程:

        将console_buffer复制到last_command中,console_buffer是命令(输入的命令),并以run_command函数去执行命令。

        run_command(const char *cmd,int flag),clear_ctrlc()中断执行。

        CFG_CBSIZE,规定的最长命令码长度一般为256/512。

        将输入的指令复制到cmdbuf中进行解析,根据‘\’‘\\’‘;’等输入规则进行解析。

        parse_line负责进一步对指令进行解析,将md 30000000 10解析为:

argv[0]="md";
argv[1]="30000000";
argv[2]="10";

        find_cmd(argv[0]);用于查找是否有这个指令,将找到的指令写到cmdtp中,repeatable支持了在命令输入时的回车重复,max_args设定了最大的参数个数。

        cmdtp->cmd存有命令的函数指针。(cmdtp->cmd) (cmdtp,flag,argc,argv)。以函数指针去调用用于执行的对应函数。

        命令执行在于find_cmd对指令的查找,取决于uboot对命令体系的机制(注册、存储、管理、索引等)。

        存储指令集的方法常用的有两种:①数组:大小不好确定,很容易造成浪费或不够。②链表:虽然灵活但开销大。uboot只是一个裸机程序并没有使用上面的两个方式,而是使用了结构体进行存储。

struct cmd_tbl_s {
       char *name;//命令名称
       int maxargs;//最大参数个数
       int repeatable;//是否支持重复执行(回车)
       int (*cmd)(struct cmd_tbl_s *, int, int, char *[]);//命令所对应的函数指针
       char *usage;//命令短的帮助信息
       #ifdefCFG_LONGHELP
       char *help;//命令长的帮助信息
        #endif
        #ifdef CONFIG_AUTO_COMPLETE
        int  (*complete)(intargc, char *argv[], charlast_char, intmaxv, char *cmdv[]);
                               //函数指针,指向自动补全指令的函数
        #endif
};

        对于一个命令来说,需要解决两个问题其一是填充结构体实例,其二是给命令结构体附加特点的段属性。

        给命令结构体附加特点的段属性,链接时会带有该段属性内容链接在一起排列(什么东西放什么地方)。用户自定义段命令与命令是相互紧贴的,链接器工作时会将段属性相互放在一起。命令放在u_boot.bin中,同时命令是无序的,但一定是放在一起的。段有起始与结束地址,所以知道在哪开始,在哪结束。

        在uboot.lds中,uboot不支持命令在启动后进行拓展,所以使用了一种依靠链接器与段方法去实现,像是一个无序的数组。

#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}

        其中,cmd_tbl_t是一个结构体,struct_Section是一个宏。以U_BOOT_CMD(version,1,1,do_version,"version-print monitor version\n",NULL);为例。

        使用##做连字符,U_BOOT_CMD宏,关键在于结构体变量名与段属性。段属性就是标签,附加了用户自定义的段属性,以保证链接时候数据结构能链接到一起,每个函数都对应了一个U_BOOT_CMD组成的指令。

        本章先写到这,下一章我们将对find_cmd函数做解析。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值