command.h中:
#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}
参数解释:
name:命令名字
maxargs:命令参数个数最大值,CFG_MAXARGS=16
rep:可重复
cmd:操作函数
usage:简单的帮助信息
help:详细的帮助信息
把Struct_Section展开:
cmd_tbl_t __u_boot_cmd_##name __attribute__ ((unused,section (".u_boot_cmd"))) = \
{#name, maxargs, rep, cmd, usage, help}
__attribute__ ((unused,section (".u_boot_cmd")))指明了结构体的段属性。
结构体的段属性可以在结构体定义时被指定(这个段指的是连接脚本中数据段,代码段,bss段,和自己定义的段),
强制指明了结构体的段属性后,那么编译链接的时候,它就应该链接在链接脚本指明的段中。例如把uboot命令结构
体指明为.u_boot_cmd段属性,那么它编译链接的时候应该链接到.u_boot_cmd段中,而不是连接在数据段,代码段
等其他段。
uboot命令都被指定了段属性,都链接在链接脚本里定义uboot_cmd_start与uboot_cmd_end之间。
cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage, help}
定义一个cmd_tbl_t结构体,其中这个结构体的成员就是#name, maxargs, rep, cmd, usage, help,
亦即宏U_BOOT_CMD的作用。
仿照bootm命令添加一个hello命令:
bootm命令对应/common/com_bootm.c文件,参考之:
//用U_BOOT_CMD(name,maxargs,rep,cmd,usage,help)定义cmd_tbl_t结构体
U_BOOT_CMD(
bootm, CFG_MAXARGS, 1, do_bootm,
"bootm - boot application image from memory\n",
"[addr [arg ...]]\n - boot application image stored in memory\n"
"\tpassing arguments 'arg ...'; when booting a Linux kernel,\n"
"\t'arg' can be the address of an initrd image\n"
#ifdef CONFIG_OF_FLAT_TREE
"\tWhen booting a Linux kernel which requires a flat device-tree\n"
"\ta third argument is required which is the address of the of the\n"
"\tdevice-tree blob. To boot that kernel without an initrd image,\n"
"\tuse a '-' for the second argument. If you do not pass a third\n"
"\ta bd_info struct will be passed instead\n"
#endif
);
步骤1:/common/ 目录下增加hello_cmd.c文件
cmd_hello.c(仿照Cmd_bootm.c):
#include <common.h>
#include <watchdog.h>
#include <command.h>
#include <image.h>
#include <malloc.h>
#include <zlib.h>
#include <bzlib.h>
#include <environment.h>
#include <asm/byteorder.h>
//实现hello命令的操作函数,打印hello world!及其参数
//在uboot命令行输入命令及参数后,执行do_hello()函数前不知哪里已经把命令和参数保存在argv[]数组中。
//参数个数已被保存在argc中
int do_helleo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
int i;
printf("hello world!,%d\n",argc);
for(i=0;i<argc;i++)
{
print("argv[%d]:%s\n",i,argv[i]);
}
return 0;
}
U_BOOT_CMD(
hello, CFG_MAXARGS, 1, do_hello,
"hello short help\n",
"hello,long help\n"
);
步骤2:修改common目录下的Makefile,添加com_hello.o,再编译即可。
测试:烧写编译后的u-boot.bin,uboot命令行下输入:hello abc efg
输出:
hello world!,3
argv[0]:hello
argv[1]:abc
argv[2]:efg