// uboot 主循环
main_loop()
run_command()
// 解析输入命令
argc = parse_line (finaltoken, argv)
// 根据argv[0] 这个字符串找到对应的结构体cmdtp
cmdtp = find_cmd(argv[0])
// 所有的cmd 结构体都存在一介于__u_boot_cmd_start
// 和__u_boot_cmd_end 之间的位置。这两个值位于链接脚本中
for (cmdtp = &__u_boot_cmd_start; cmdtp != &__u_boot_cmd_end; cmdtp++) {
if (strncmp (cmd, cmdtp->name, len) == 0) {
if (len == strlen (cmdtp->name))
return cmdtp; /* full match */
}
}
}
包括命令的名字,最大参数个数,帮助信息等等。
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
};
搜索 __u_boot_cmd_start 发现该值定义在 链接脚本中,如下:
可见所有命令都被存储在 u_boot_cmd 段中。以此为线索继续搜索
发现最终都被这个 U_BOOT_CMD 的宏所使用,从该宏可以看出这个宏做的事情就是创建 cmd_tbl_t 类型的结构体对象。
随便找到一处使用 U_BOOT_CMD 的地方来看一下:
发现实现一个uboot里的命令也非常方便,概况一下就是:
在common 目录下建立文件名为cmd_my_hello.c ,内容如下,其中头文件直接挪用的cmd_bootm.c 的:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef CONFIG_OF_FLAT_TREE
#include
#endif
int do_hello (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){
printf("hello, world\n");
}
U_BOOT_CMD(hello, CFG_MAXARGS, 1, do_hello,
"test my boot cmd",
"help information,\n"
"multyline, help information"
);
将自己新建的文件添加到同目录的Makefile 中,即修改common/Makefile:
然后再重新make 就行了。
笔者的ubuntu 里有两个用户book 和zqxl ,uboot源码的的owner 是 book ,我用ssh 以zqxl 登陆时,无法make,报错如下:
用book 就没这个问题,可以成功编译:
怀疑文件读写权限的缘故,但是期间也试过chmod 777 u-boot-1.1.6 -R
,但是好像还是不行。将整个uboot 源码文件所属的owner 和group 都修改成zqxl 后,果然就用zqxl 的身份编译过了。修改owner 和group 的命令如下:
编译内核的时候也遇到这个问题了,为此单独写了一篇文章。