转载: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. 概率论 - BZOJ - 4001 TJOI2015

    TJOI2015 Problem's Link ---------------------------------------------------------------------------- ...

  2. VS2013 连接 MySQL

    1.安装必须的工具: mysql-connector-net-6.8.3 mysql-installer-community-5.6.16.0.msi mysql-for-visualstudio-1 ...

  3. 《精通CSS》读书笔记(一)

    最近新添16本书,目前开始看陈剑瓯翻译的<精通CSS——高级Web标准解决方案>(Andy Budd, CSS Mastery -- Advanced Web Standards Solu ...

  4. 使用PULL解析XML文件

    转载博文1:http://blog.csdn.net/wangkuifeng0118/article/details/7313241 XmlPull和Sax类似,是基于流(stream)操作文件,然后 ...

  5. 29Spring_Autowriter的一些疑惑(很重要)

    我用一个Autowriter去注解一个属性,而且我没有在Spring的配置文件中的bean.xml中注册bean(<bean id=""...);那么这个注解有用吗?答案是不 ...

  6. MyBatis的优缺点

    优点: 1.简单易学 mybatis本身就很小且简单.没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现 ...

  7. 多媒体开发之rtp 打包发流--- 从h264中获取分辨率

    http://blog.csdn.net/DiegoTJ/article/details/5541877 http://www.cnblogs.com/lidabo/p/4482684.html 分辨 ...

  8. 多个return和一个return

    //一个returnnamespace CleanCSharp.Methods.Dirty { class MethodExitPoints { public string GenerateAgeAp ...

  9. bootstrap基础学习二篇

    这篇学习网格系统(Grid System) Bootstrap 提供了一套响应式.移动设备优先的流式网格系统,随着屏幕或视口(viewport)尺寸的增加,系统会自动分为最多12列. 1.网格选项: ...

  10. powershell---高级函数的介绍

    https://guhuajun.wordpress.com/2009/05/11/windows-powershell-v2-介绍(5)-高级函数(上)/ https://guhuajun.word ...