我们用u-boot启动开发板后,串口输出,我们进入到命令终端,这里我们就是进入了u-boot的命令模式。我们输入mtd w 0就会打印出0地址的内容,输入print就会打印环境变量等信息。那,这是怎么实现的。我们猜测,这些命令可能保存在一个结构体中,这个结构体包含命令名,参数等,然后根据这些argv[]调用到功能函数。有关于u-boot的命令我们u-boot-1.1.6\common\Main.c下的run_command函数
这里定义了一些指针
下面的这个是分析我们输入的命令,比如我们输入两个不同的命令,中间用;隔开,就会打印两次不同的结果
下面这个是来分析我们传入的参数argv[]和保存起来,中间的cmdtp结构体就是我们刚才假设的那个结构体,有名称,最大参数,重复等,int (*cmd)(struct cmd_tbl_s *, int, int, char *[]);这句就是命令对应要执行的功能函数,char *usage; /* Usage message (short) */和char *help; /* Help message (long) */是短的和长的帮助信息。短的:help 长的:help ls
find_cmd把找到的命令对应结构体传到cmdtp中,那find_cmd是怎么找到的,我们进去find_cmd 去看看
中间的__u-boot_cmd_start和__u-boot_cmd_end看来是所有命令的开始到结束,我们想来我们之前在u-boot.lds
中我一个相同的,如下:
. = .;
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) } //u-boot自定义的段
__u_boot_cmd_end = .;
这里我们知道for (cmdtp = &__u_boot_cmd_start;cmdtp != &__u_boot_cmd_end; cmdtp++)这个循环是从头到尾找到命令(匹配命令名称),我们想知道这些命令都有什么,我们在source insight中搜索u_boot_cmd,找到command.h中有一句#define Struct_Section __attribute__ ((unused,section (".u_boot_cmd"))),显然这是一个命令的结构体,我们举例我们的bootm(启动内核命令),搜索找到cmd_bootm.c文件下的
看来U_BOOT_CMD是重点所在里面存在是命令的功能函数和名称等,再搜索U_BOOT_CMD在哪里定义
#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help)。正好对应U_BOOT_CMD里的bootm, CFG_MAXARGS, 1, do_bootm还有help。
我们进去功能函数看看
到这里,我们知道了,一个命令的实现,需要有一个包含命令信息的结构体,还有具体的功能函数,所以,我们假如要自己写u-boot命令的话,只需要自己写一个类似上面U_BOOT_CMD();的函数还有写功能函数类似do_bootm这两个就行。并且把它放进去command目录中,在command的Makefile中假如链接地址就行。
例如:加了cmd_hello.o