转载:http://blog.csdn.net/shengzhadon/article/details/52766263

U_BOOT_CMD是一个宏定义,具体功能是定义一个struct cmd_tbl_s的结构体变量,U_BOOT_CMD宏传递的参数是该结构体变量的成员变量。通过U_BOOT_CMD定义的变量会通过脚本链接到uboot指定的一个section中,然后可以通过find_cmd遍历这个section找到这个cmd,可以通过run_command(cmd, flag)函数执行具体命令。

uboot的命令都存放在uboot/common/目录下,可以在该目录下的Makefile中添加编译命令的选项。如,网络的编译选项如下:

obj-$(CONFIG_CMD_NET) += cmd_net.o  

网络的具体命令是再uboot/common/cmd_net.c中定义的,如nfs命令

#if defined(CONFIG_CMD_NFS)
static int do_nfs(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
return netboot_common(NFS, cmdtp, argc, argv);
} U_BOOT_CMD(
nfs, , , do_nfs,
"boot image via network using NFS protocol",
"[loadAddress] [[hostIPaddr:]bootfilename]"
);
#endif

可以看出nfs命令是通过U_BOOT_CMD宏定义“注册“的,并关联上do_nfs(...)函数,执行具体功能。这里的U_BOOT_CMD是在uboot/include/command.h文件中定义的,如下:

#define U_BOOT_CMD(_name, _maxargs, _rep, _cmd, _usage, _help)      \
U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, NULL)

U_BOOT_CMD_COMPLETE定义紧挨着,如下:

#define U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, _comp) \
ll_entry_declare(cmd_tbl_t, _name, cmd) = \
U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, \
_usage, _help, _comp);

这里可以看出是一个赋值语句(其实“=”前面是定义一个变量,后面赋值)。“=”后面的宏定义紧挨着,如下:

#define U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd,      \
_usage, _help, _comp) \
{ #_name, _maxargs, _rep, _cmd, _usage, \
_CMD_HELP(_help) _CMD_COMPLETE(_comp) }

注:这里的“#”,作用是将_name传递的值字符串化。_CMD_HELP和_CMD_COMPLETE就是取本身(具体宏定义在本文件command.h中)。

可以看出,这个宏定义的作用就是将U_BOOT_CMD传递的参数放在大括号内。

“=”前面的ll_entry_declare也是一个宏定义,具体在uboot/include/linker_lists.h中,如下

#define ll_entry_declare(_type, _name, _list)                \
_type _u_boot_list_2_##_list##_2_##_name __aligned() \
__attribute__((unused, \
section(".u_boot_list_2_"#_list"_2_"#_name)))

注:这里的"##"表示连接作用。即##_list##表示用_list变量的值替换当前位置。

即通过_type传递变量类型,_name和_list传递组成变量名称的字符串,然后将该变量放在section中,section的名称也由_name和_list命令传递。这里的__aligned(4)是指定定义的变量4字节对其,__attribute是选择未使用的section,可以在理解原理时忽略掉。

这里的_type=cmd_tbl_t,后者的定义如下:

typedef struct cmd_tbl_s    cmd_tbl_t;  

即cmd_tbl_t就是cmd_tbl_s,定义如下:

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 * const []);
char *usage; /* Usage message (short) */
#ifdef CONFIG_SYS_LONGHELP
char *help; /* Help message (long) */
#endif
#ifdef CONFIG_AUTO_COMPLETE
/* do auto completion on the arguments */
int (*complete)(int argc, char * const argv[], char last_char, int maxv, char *cmdv[]);
#endif
};

如前所述,U_BOOT_CMD的作用就是定义一个结构体变量(struct cmd_tbl_s),并将其存放再uboot的没有被占用的section中。展开就是:

struct cmd_tbl_s _u_boot_list_2_cmd_2_##_name = {
#_name, _maxargs, _rep, _cmd, _usage, _help, NULL
};

注:该变量属性是4字节对齐(__aligned(4) ),存放在未被使用的section中,并将该section命名为【".u_boot_list_2_"#name】(__attribute__((unused, section(".u_boot_list_2_"#name))))。

举例:

命令nfs

U_BOOT_CMD(
nfs, , , do_nfs,
"boot image via network using NFS protocol",
"[loadAddress] [[hostIPaddr:]bootfilename]"
);

即为:

struct cmd_tbl_s _u_boot_list_2_cmd_2_nfs = {
"nfs", , , do_nfs,
"boot image via network using NFS protocol",
"[loadAddress] [[hostIPaddr:]bootfilename]", NULL
};

将_u_boot_list_2_cmd_2_nfs变量4字节对齐存放在未被使用的uboot的section中,该section被命名为.u_boot_list_2_nfs。

Uboot命令U_BOOT_CMD的更多相关文章

  1. Uboot命令U_BOOT_CMD分析

    其中U_BOOT_CMD命令格式如下: U_BOOT_CMD(name,maxargs,repeatable,command,"usage","help") 各 ...

  2. uboot命令分析+实现【转】

    转自:http://xouou.iteye.com/blog/2150061 先贴一个重要结构,位于uboot/include/command.h,这个结构代表每个uboot命令 struct cmd ...

  3. Uboot 命令行 介绍

    背景 基本上,本文转载自:<ARM板移植Linux系统启动(五)Uboot命令行> 上次说到uboot的启动方式,最后会使用autoboot(自主模式)尝试引导kernel,如果失败或者被 ...

  4. 1.ok6410移植bootloader,移植u-boot,学习u-boot命令

    ok6410移植u-boot 既然是移植u-boot当然首先需要u-boot源码,这里的u-boot代码是由国嵌提供的. 一.配置编译u-boot A. 解压 u-boot 压缩文件 B. 进入解压生 ...

  5. U-Boot命令大全(功能参数及用法)

    U-Boot上电启动后,按任意键可以退出自动启动状态,进入命令行. U-Boot 2010.03 (Sep 25 2011 - 16:18:50)     DRAM: 64 MB     Flash: ...

  6. 编译u-boot命令和u-boot常用命令

    一.编译u-boot命令 1.配置开发板 #make TQ2440_config 2.编译 #make all 3.交叉编译器是crosstools_3.4.5_softfloat” 使用4.3.3版 ...

  7. bootargs中的环境变量说明和一些常用的uboot命令

    bootargs中的环境变量说明和一些常用的uboot命令 一些常见的uboot命令:Help [command]在屏幕上打印命令的说明Boom [addr]启动在内存储器的内核Tftpboot通过t ...

  8. Uboot mmc命令解析&NAND flash uboot命令详解

    转载:http://blog.csdn.net/simonjay2007/article/details/43198353 一:mmc的命令如下: 1:对mmc读操作 mmc read addr bl ...

  9. securecrt中进入uboot命令行时,出现无法键入任何指令的问题解决方法

    securecrt中进入uboot命令行时,出现无法键入任何指令的问题解决方法 可能出现以下几种情况 1.securecrt在创建连接时,忘记取消勾选流控: 2.usb转串口线坏了3.uboot有问题 ...

随机推荐

  1. easyui添加删除tooltip

    /** * 扩展两个方法 */$.extend($.fn.datagrid.methods, { /** * 开打提示功能 * @param {} jq * @param {} params 提示消息 ...

  2. windows 10 搭建go环境

    1. 到 https://golang.org/ 下载go 的msi安装包.安装后 GOROOT 已经自动帮你设置好. 2.设置GOPATH 不能跟 GOROOT 同一个目录.到系统环境变量里新增一个 ...

  3. LPCTSTR —— 摘自百度百科

    LPCTSTR用来表示字符是否使用UNICODE. 如果程序定义了UNICODE或者其他相关的宏,那么这个字符或者字符串将被作为UNICODE字符串,否则就是标准的ANSI字符串. 类型理解:L,表示 ...

  4. CAEmitterCell 和 CAEmitterLayer具体解释

    一.在 UIKit 中,粒子系统由两部分组成: 1·      一个或多个  CAEmitterCells :发射器电池能够看作是单个粒子的原型(比如,一个单一的粉扑在一团烟雾).当散发出一个粒子,U ...

  5. ORACLE之常用FAQ V1.0

    [B]第一部分.SQL&PL/SQL[/B][Q]怎么样查询特殊字符,如通配符%与_[A]select * from table where name like 'A\_%' escape ' ...

  6. log4j配置文件

    log4j.rootLogger=INFO,CONSOLElog4j.addivity.org.apache=truelog4j.appender.stdout=org.apache.log4j.Co ...

  7. GCC命令基础

    gcc命令使用GNU推出的基于C/C++的编译器,是开放源代码领域应用最广泛的编译器,具有功能强大,编译代码支持性能优化等特点, 现在很多程序员都应用GCC,怎样才能更好的应用GCC. 目前,GCC可 ...

  8. 关于Bootstrap的理解

    Web开发领域存在大量的反复劳动.以创建一个菜单为例,不同的人或是同一个人在不同的时期去构建一个菜单.他创建出来的菜单格式都会存在差异:随着构件的菜单越来越多,我们会发现假设将构建菜单这件事形成一个框 ...

  9. Spring中bean的作用范围

    singleton作用域: Spring的scope的默认值是singleton Spring 只会为每一个bean创建一个实例,并保持bean的引用. <bean id="bean的 ...

  10. java基础---->Java中异常的使用(二)

    这一篇博客用例子讲述一下异常的处理过程.那些 我们一直惴惴不安 又充满好奇的未来 会在心里隐隐约约地觉得它们是明亮的. 异常的执行过程 一.实例一:return语句 public class Exce ...