当前位置: 首页 > article >正文

笔记整理—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函数做解析。


http://www.kler.cn/a/287603.html

相关文章:

  • 使用win32com将ppt(x)文件转换为pdf文件
  • Cursor安装Windows / Ubuntu
  • 【ubuntu18.04】vm虚拟机复制粘贴键不能用-最后无奈换版本
  • 【论文复现】STM32设计的物联网智能鱼缸
  • SpringMVC数据校验、数据格式化处理、国际化设置
  • 数仓建设之Oracle常见语法学习
  • 大佬借助ChatGPT写论文发刊到手软,四个步骤20个顶级学术提示词指令
  • MyBatis-SQL-语句执行流程
  • UE5 UMG UI编辑器工作流
  • mybatis if标签判断字符串是否相等
  • 面试基本内容
  • 【GD32】RT-Thread实时操作系统移植(GD32F470ZGT6)
  • 中介者模式详解
  • Pytorch实现多层LSTM模型,并增加emdedding、Dropout、权重共享等优化
  • Python 爬虫爬取京东商品信息
  • 会赢的!(牛客)
  • 买电脑如何选择显卡?
  • 10、Flink 动态表之更新和追加查询详解
  • 【React】Redux-toolkit 处理异步操作
  • 网络是怎样连接的
  • 数美Android SDK
  • JavaWeb笔记整理11——Nginx反向代理Tomcat
  • K8S ReplicaSet
  • 安装office过程中遇到的一系列问题及解放方案(Windows)
  • 深度学习100问37:什么是Gated RNN 框架
  • 一份高质量的测试用例如何养成?