转:http://www.embedu.org/Column/Column464.htm

作者:曾宏安,华清远见嵌入式学院讲师。

u-boot是嵌入式系统中广泛使用的一种bootloader。它不仅支持众多的平台和参考板,而且支持丰富的命令,可以让用户对开发板进行各种操作。关于u-boot使用和移植的资料很多,这里不再赘述。下面用问答的方式介绍u-boot中命令的实现机制。

Q1: u-boot中命令的实现代码在什么地方?

A1: 在u-boot源码的common目录下。通常一个或多个命令在对应的某个C文件中实现。如果用户要增加一个新命令的话,要在common目录下添加对应的C文件,并在Makefile中指定编译该文件。

Q2: 能不能给个命令的实现模板先?

A2: #include <common.h>
               #include <command.h>

int do_hello(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
               {
                       printf(“hello world\n”);
                       return 0;
               }
               U_BOOT_CMD(hello, CONFIG_SYS_MAXARGS, 1, do_hello, “usage info”,  “help info”);

以下是上面代码的解释:

U_BOOT_CMD是u-boot中定义的宏,上面的宏定义展开后如下:

cmd_tbl_t __u_boot_cmd_hello Struct_Section = {“hello”, CONFIG_SYS_MAXARGS, 1, do_hello, “usage info”, “help info”};

这下清楚了,实际上就是定义一个类型为cmd_tbl_t的结构体并对其赋值。

u-boot中每个命令都用这样的一个结构体来描述,类型定义如下:

typedef struct cmd_tbl_s cmd_tbl_t;
        struct cmd_tbl_s {
                char *name;        // 命令的名称
                int maxargs;        // 最多支持的参数的个数
                int repeatable;        // 是否可重复执行
                int (*cmd)(struct cmd_tbl_s *, int, int, char *const[]);        // 命令对应的处理函数
                char *usage;        // 命令简要使用信息
                char *help;        // 命令详细帮助信息
        }

成员cmd是个函数指针,需要指向该命令对应的处理函数。这也是在前面的模板中先定义一个处理函数的原
因。所有命令的处理函数的接口都是一致的:参数cmdtp指向命令对应的cmt_tbl_t结构体;参数flag可以忽略不处理;参数argc和参数
argv的作用和它们在main函数中是一样的。

Q3: 当用户输入命令后,u-boot是如何执行的?

A3: 前面用U_BOOT_CMD定义结构体时用到了另外一个宏Struct_Section,它表示把该结构体放到一个专门的段。u_boot_cmd,没错,u-boot中所有命令对应的结构体都集中放在这个段里,该段里的内容会被包含在编译好的u-boot里。

这下就容易理解了:u-boot接收到用户的命令后在.u_boot_cmd段中依次查找每个
cmd_tbl_t,根据成员name比较是否和用户命令匹配。若成功则执行第三个成员cmd指向的函数,否则查找下个cmd_tbl_t。具体的实现请
参考u-boot中的函数find_cmd的代码。

小结:在我看来,u-boot不仅是一个功能强大的bootloader,而且是一个很好的嵌入式编程的学习对象,其中很多编程的思想和实现的方法都值得大家借鉴。

最新文章

  1. 《对象及DOM知识点及其应用1》
  2. [No000025]停止自嘲—IT 技术人必须思考的 15 个问题
  3. POJ3013 Big Christmas Tree(最短路径树)
  4. GPIO裸机编程
  5. ubuntu14.04安装注意事项
  6. ifram一些常用的知识点
  7. mybatis like 查询
  8. 优化之zencart第一时间修改原始内容
  9. Vector的浅析
  10. TOP命令详解(负载情况)
  11. JAVA 键盘输入数组,输出数组内容和最大值、最小值
  12. 如何解决Reporting Services目录数据库文件存在的问题
  13. springboot~lombok使用总结
  14. 【python 字符串】 字符串的相关方法(一)
  15. MongoDB 分片键的选择与案例
  16. JVM配置参数详解
  17. FAL_CLIENT和FAL_SERVER参数详解
  18. spring 判断非空提示断言
  19. 【BZOJ 3036】 3036: 绿豆蛙的归宿 (概率DP)
  20. OpenGL ES2学习笔记(6)-- Line Strip和Line Loop

热门文章

  1. SqlServer存储过程中使用事务,示例
  2. 获取file中字段,写入到TXT文件中
  3. java web 资源文件读取
  4. Oracle事务处理
  5. 获取GUID的方法
  6. 共享变量 static
  7. Django 如何实现文件下载
  8. linux下环境变量设置的问题
  9. centos安装更新Python2.7以及pip的安装
  10. 前端读者 | ES6知识点概述