1:回归到main_loop
uboot启动第二阶段的最后,进入死循环main_loop()函数,命令行中没输出一次命令,就会执行一次main_loop函数,完成一次命令的获取、解析和执行。
2:uboot命令体系的实现原理
uboot中里面维护了很多命令,每个命令对应一个结构体变量,当我们在命令行输入一个命令时。这时就涉及如何去维护这些命令的问题,一般的方法有两种,数组或者链表,但是数组的缺陷在开始的时候需要确定数组的大小,链表的话效率比较低,所以uboot使用了另一种方式。uboot中一个命令对应一个__u_boot_cmd_命令结构,并且绑定了一个do_命令函数。
uboot里面给命令添加了一个段属性,所以在链接的时候相同段属性的代码会连续的发到一起(命令的顺序是不定的),所以指定了段属性的起始地址和结束地址,那么我们就可以通过指针的方式去访问这些数据,这样实现方式在存储方面和数组类似,但是有避免数组大小一开始就需要确定的局限性。所以在添加和删除命令的时候很简单就可以实现。
3:结构体cmd_tbl_s,命令结构体
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
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 CFG_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
};
|
参数解析:
name:命令的名字
maxargs:命令允许传入最多的参数个数
repeatable:命令是否允许连续执行(输入一次命令后,按下回车还会执行之前的命令)
cmd:命令对应的执行函数
usage:命令的短说明
help:命令的长说明
4:两个宏定义U_BOOT_CMD和Struct_Section
1
2
|
#define Struct_Section __attribute__ ((unused,section (".u_boot_cmd")))
#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}
|
Struct_Section宏的作用是添加段属性 .u_boot_cmd,段属性的起始地址在链接脚本中有指定。
U_BOOT_CMD宏的作用是实例化一个cmd_tbl_t类型的结构体__u_boot_cmd_##name,并且在实例化的时候同时初始化结构
##name:##是转义字符,效果是将##name用name替代
#name:#转义字符,效果是将name转成字符串类型的‘name’
5:添加uboot命令
方法1:在原有的.c文件中加
uboot命令很多都保存在uboot/common/command.c文件中,所有要添加uboot命令只需要在command.c按照其他的命令的格式添加即可
方法2:自己创建.c文件并添加命令
首先在uboot/common/中创建一个.c文件,然后添加U_BOOT_CMD宏和对应的命令函数,需要注意的是要添加相应的头文件,然后在uboot/common/Makefile下添加xxx.o,目的的编译的时候能将添加的.c文件编译链接进去。
本文转自 菜鸟养成记 51CTO博客,原文链接:http://blog.51cto.com/11674570/1926573