U_BOOT_CMD命令解析

11 篇文章 0 订阅

在UBOOT当中,各个命令是通过U_BOOT_CMD这个宏来定义出来的。

先来看UBOOT当中关于U_BOOT_CMD这个宏的定义:

#define Struct_Section __attribute__ ((unused,section (".u_boot_cmd")))

由此可见,被U_BOOT_CMD 定义过的结构体,最终回被放到一个u_boot_cmd 段中。可以通过readef 工具进行验证,会发现在生成的目标文件中,确实多了一个.u_boot_mcd 段。

再看一下u-boot 的链接脚本,其中有这么一段:

.u_boot_cmd : {

__u_boot_cmd_start = .;

*(.u_boot_cmd)

__u_boot_cmd_end = .;

}

uboot_end_data = .;

可以发现该脚本将所有的.u_boot_cmd 放在了一起。而起还定义了两个常量__u_boot_cmd_start 和__u_boot_cmd_end 还表示所有命令的起始位置和结束位置。最后只需对该段进行遍历就可以得到所有的命令

了。



#define U_BOOT_CMD(name,maxargs,rep,cmd,usage) /
cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage}

这样一来,凡通过U_BOOT_CMD定义的cmd_tbl_t变量会全部被放在.u_boot_cmd段当中(可以看UBOOT的链接脚本xxx.lds),具体怎么放是链接器的工作。

这里要看的是##name和#name这两个操作.##name将字符直接跟在后面, #name会将name这个字符中以“..."的形式放置。

例如:定义一个命令boot

U_BOOT_CMD(boot, 0, 0, fun, "boot xxx");


展开以后会变成:

cmd_tbl_t __u_boot_cmd_boot __attribute___((unused, section(".u_boot_cmd"))) = {"boot", 0, 0, fun, "boot xxx"}

大部分基本不变,将Struct_Section展开了,还将##name换成了boot, 将#name换成了"boot"。应该不难看出##/#的作用吧。

从上面来看,我们是不是可以在程序运行时去定义一个变量呢??我们可以通过##xxx来定义一个变量,然后还可以通过这种形式来使用它。

总体来说是通过宏定义来定义变量,准确地说应该是结构体变量。并且把这些同一种结构体的变量放在一个段中,充分的利用了连接器的作用,很少看到,但是确实很实用。这样做的好处是所有开发各个模块的研发人员不必去维护一个全局的结构体数组,而且你也不知道别人用的是数组中的哪一个下表,这种方法就很好的解决了这种烦恼,值得推广。


转载:http://blog.sina.com.cn/s/blog_6276db0e0101b1qs.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值