zoukankan      html  css  js  c++  java
  • uboot中的命令体系

    一、uboot的命令体系介绍以及实例分析:

     U-Boot 的命令实现大多在 common 目录下。在该目录下命令的代码文件都是以“ cmd_”开头的,如下图所示:

          

      其中每一个文件都是一个命令实现的代码文件,而且文件名和命令名称是相关的,例如 cmd_nand.c 是实现 nand 命令的文件,从而实现模块化,这样就可以方便我们管理和添加自己的命令。

    下面,我们用一个示例来讲解u-boot中如何管理这套命令体系的,以及如何添加一个自定义的命令。

        

    这里涉及了几个要点,第一个是cmd_tbl_t结构体:

      

      不难看出cmd_tbl_t结构体主要是包含了命令的一些信息,最关键的是想通过回调函数的形式来实现用户的自定义功能。

    那么接下来来分析一个重点 U_BOOT_CMD:

      

      这里会涉及一些编译器相关的知识,struct_Section的意思是想将一个结构体标记成".u_boot_cmd"属性(__attribute__是编译器的扩展属性,具体可以查看gcc手册)。而这里的 __u_boot_cmd##name 的含义是将 name添加上 __u_boot_cmd_ 前缀。

    于是我们可以将最上面的version例子来拆解:

      

    二、uboot中对命令的注册、存储、索引:

      结合上面的例子,发现使用U_BOOT_CMD宏可以向uboot添加一条命令, 通过填充该宏的参数,完成对该条命令对应的结构体的填充,便完成了注册的功能。

    而在U_BOOT_CMD宏中给每条命令声明了 用户自定义段属性,使得在链接时会将具有该段属性的结构体按照顺序排布在一起,类似于结构体数组,这就是uboot命令的存储方式。

    既然在uboot中存储了具有段属性的结构体数组,那么在查找命令的时候,只需要遍历该数组,如果找到返回该命令结构体的首地址即可。在uboot中是通过find_cmd函数查找命令的,如下图所示:

     1 /**
     2  * find command table entry for a command
     3  * 如果查找成功,返回结构体首地址
     4  */
     5 cmd_tbl_t *find_cmd_tbl (const char *cmd, cmd_tbl_t *table, int table_len)
     6 {
     7     cmd_tbl_t *cmdtp;
     8     cmd_tbl_t *cmdtp_temp = table;    /*Init value */
     9     const char *p;
    10     int len;
    11     int n_found = 0;
    12 
    13     /*
    14      * Some commands allow length modifiers (like "cp.b");
    15      * compare command name only until first dot.
    16      */
    17     len = ((p = strchr(cmd, '.')) == NULL) ? strlen (cmd) : (p - cmd);
    18 
    19     for (cmdtp = table; cmdtp != table + table_len;cmdtp++) {
    20         if (strncmp (cmd, cmdtp->name, len) == 0) {
    21             if (len == strlen (cmdtp->name))
    22                 return cmdtp;    /* 完全匹配 */
    23 
    24             cmdtp_temp = cmdtp;    /* abbreviated command ? */
    25             n_found++;
    26         }
    27     }
    28     if (n_found == 1) {            /* exactly one match */
    29         return cmdtp_temp;
    30     }
    31 
    32     return NULL;    /* 没有找到命令 */
    33 }
    34 
    35 cmd_tbl_t *find_cmd (const char *cmd)
    36 {
    37     /* __u_boot_cmd_end 和 __u_boot_cmd_start 是链接脚本中标记命令结构体数组的首尾地址*/
    38     int len = &__u_boot_cmd_end - &__u_boot_cmd_start;
    39     return find_cmd_tbl(cmd, &__u_boot_cmd_start, len);
    40 }
    View Code

    链接脚本(u-boot.lds):

      

     三、向uboot中添加自定义命令:

      通过分析,我们也可以自己实现一个uboot命令。

      1. 在common文件夹下建立一个以"cmd_xxx"的文件
      2. 参考cmd_version.c并结合具体的业务修改。
      3. 修改uboot/common/Makefile,添加上xxx.o(xxx为对应的命令文件): 
      4. 重新编译链接,下载烧录测试。

      这样一个uboot命令就添加成功了。当然我们这里只是简单的介绍了uboot中的命令体系,实际的产品需要根据您的业务来编写具体的命令函数等。

  • 相关阅读:
    导包路径
    django导入环境变量 Please specify Django project root directory
    替换django的user模型,mysql迁移表报错 django.db.migrations.exceptions.InconsistentMigrationHistory: Migration admin.0001_initial is applied before its dependen cy user.0001_initial on database 'default'.
    解决Chrome调试(debugger)
    check the manual that corresponds to your MySQL server version for the right syntax to use near 'order) values ('徐小波','XuXiaoB','男','1',' at line 1")
    MySQL命令(其三)
    MySQL操作命令(其二)
    MySQL命令(其一)
    [POJ2559]Largest Rectangle in a Histogram (栈)
    [HDU4864]Task (贪心)
  • 原文地址:https://www.cnblogs.com/qiabaowei/p/8546838.html
Copyright © 2011-2022 走看看