uboot 命令构造宏分析
来源:互联网 发布:财政部会计报表软件 编辑:程序博客网 时间:2024/05/17 09:18
在uboot源码目录下include/command.h中定义了一系列宏来构造一个UBOOT CMD。下面结构是命令表中一条命令的组成
struct cmd_tbl_s{char*name;/* Command Name*/intmaxargs;/* maximum number of arguments*/intrepeatable;/* autorepeat allowed?*//* Implementation function*/int(*cmd)(struct cmd_tbl_s *, int, int, char * const []);char*usage;/* Usage message(short)*/#ifdefCONFIG_SYS_LONGHELPchar*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};
typedef struct cmd_tbl_s cmd_tbl_t; //重命名extern cmd_tbl_t __u_boot_cmd_start; //这是两个很重要的符号 后面会解释extern cmd_tbl_t __u_boot_cmd_end;接下来是几个组合的宏定义来构造出一条命令:
#define Struct_Section __attribute__((unused, section(".u_boot_cmd"), aligned(4)))#ifdef CONFIG_AUTO_COMPLETE# define _CMD_COMPLETE(x) x,#else# define _CMD_COMPLETE(x)#endif#ifdef CONFIG_SYS_LONGHELP# define _CMD_HELP(x) x,#else# define _CMD_HELP(x)#endif#define U_BOOT_CMD_MKENT_COMPLETE(name,maxargs,rep,cmd,usage,help,comp) \{#name, maxargs, rep, cmd, usage, _CMD_HELP(help),_CMD_COMPLETE(comp)}#define U_BOOT_CMD_MKENT(name,maxargs,rep,cmd,usage,help) \U_BOOT_CMD_MKENT_COMPLETE(name,maxargs,rep,cmd,usage,help,NULL)#define U_BOOT_CMD_COMPLETE(name,maxargs,rep,cmd,usage,help,comp) \cmd_tbl_t __u_boot_cmd_##name Struct_Section = \U_BOOT_CMD_MKENT_COMPLETE(name,maxargs,rep,cmd,usage,help,comp)#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \U_BOOT_CMD_COMPLETE(name,maxargs,rep,cmd,usage,help,NULL)这样当我们在定义一条命令时就可以用最后一个用户接口宏U_BOOT_CMD来定义自己的命令。以uboot现有的例子来分析:
#include <common.h>#include <command.h>int do_echo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]){int i;int putnl = 1;......return 0;}
U_BOOT_CMD(echo,CONFIG_SYS_MAXARGS,1,do_echo,"echo args to console","[args..]\n"," - echo args to console; \\c suppresses newline");
上面的宏按照顺序依次展开 最终会得到
cmd_tbl_t __u_boot_cmd_echo __attribute__((unused, section(".u_boot_cmd"), aligned(4))) ={echo,CONFIG_SYS_MAXARGS,1,do_echo,"echo args to console","[args..]\n"," - echo args to console; \\c suppresses newline"}这样就构造出了一条命令。然而我们发现include/command目录下有很多cmd_xxx.c文件。从文件名来看是对命令进行了分类,实际是也就是如此。那这么多文件是如何组织起来的呢?
那就是前面提到的两个重要符号的功劳:
extern cmd_tbl_t __u_boot_cmd_start; //这是两个很重要的符号 后面会解释extern cmd_tbl_t __u_boot_cmd_end;
这两个符号在连接文件中以下面的方式使用。其含义就是将这些左右这个类型的结构化的命令链接在一个连续的段中,以方便重定向时将uboot的命令表一起搬移到内存中指定区域。
. = ALIGN(4);. = .;__u_boot_cmd_start = .;.u_boot_cmd : { *(.u_boot_cmd) }__u_boot_cmd_end = .;
最后来看一眼command目录下的Makefile ,经便了解这些命令的使能除能配置。
include $(TOPDIR)/config.mkLIB= $(obj)libcommon.o# coreCOBJS-y += main.o......COBJS-$(CONFIG_SYS_HUSH_PARSER) += hush.o......# core commandCOBJS-y += cmd_boot.oCOBJS-y += cmd_bootm.o......COBJS-y += cmd_version.o# environmentCOBJS-y += env_common.oCOBJS-$(CONFIG_ENV_IS_IN_DATAFLASH) += env_dataflash.o......COBJS-$(CONFIG_ENV_IS_IN_SPI_FLASH) += env_sf.oCOBJS-$(CONFIG_ENV_IS_NOWHERE) += env_nowhere.o# commandCOBJS-$(CONFIG_CMD_AMBAPP) += cmd_ambapp.oCOBJS-$(CONFIG_SOURCE) += cmd_source.o......ifdef CONFIG_4xxCOBJS-$(CONFIG_CMD_SETGETDCR) += cmd_dcr.oendififdef CONFIG_POSTCOBJS-$(CONFIG_CMD_DIAG) += cmd_diag.oendifCOBJS-$(CONFIG_CMD_DISPLAY) += cmd_display.o......COBJS-$(CONFIG_CMD_FLASH) += cmd_flash.oifdef CONFIG_FPGACOBJS-$(CONFIG_CMD_FPGA) += cmd_fpga.oendifCOBJS-$(CONFIG_CMD_I2C) += cmd_i2c.o......COBJS-$(CONFIG_CMD_OTP) += cmd_otp.oifdef CONFIG_PCICOBJS-$(CONFIG_CMD_PCI) += cmd_pci.oendifCOBJS-y += cmd_pcmcia.oCOBJS-$(CONFIG_CMD_PORTIO) += cmd_portio.oCOBJS-$(CONFIG_CMD_REGINFO) += cmd_reginfo.o......COBJS-$(CONFIG_CMD_UNIVERSE) += cmd_universe.oifdef CONFIG_CMD_USBCOBJS-y += cmd_usb.oCOBJS-y += usb.oCOBJS-$(CONFIG_USB_STORAGE) += usb_storage.oendifCOBJS-$(CONFIG_VFD) += cmd_vfd.o# othersCOBJS-$(CONFIG_DDR_SPD) += ddr_spd.oCOBJS-$(CONFIG_HWCONFIG) += hwconfig.o......COBJS:= $(sort $(COBJS-y))XCOBJS:= $(sort $(XCOBJS-y))SRCS:= $(COBJS:.o=.c) $(XCOBJS:.o=.c)OBJS:= $(addprefix $(obj),$(COBJS))XOBJS:= $(addprefix $(obj),$(XCOBJS))CPPFLAGS += -I..all:$(LIB) $(XOBJS)$(LIB): $(obj).depend $(OBJS)$(call cmd_link_o_target, $(OBJS))$(obj)env_embedded.o: $(src)env_embedded.c $(obj)../tools/envcrc$(CC) $(AFLAGS) -Wa,--no-warn \-DENV_CRC=$(shell $(obj)../tools/envcrc) \-c -o $@ $(src)env_embedded.c$(obj)../tools/envcrc:$(MAKE) -C ../tools########################################################################## defines $(obj).depend targetinclude $(SRCTREE)/rules.mksinclude $(obj).depend#########################################################################
可以使用 COBJS-y += cmd_usr.o方式或是条件编译方式COBJS-$(CONFIG_CMD_USR) += cmd_usr.o 来使能命令编译。
尾巴:如果要为uboot添加自定义命令,我们最好在command目录下新建一个cmd_usr.c文件,按照上述规则来构建自己的命令。同时要修改Makefile 来使能自定义命令编译就可以了。 0 0
- uboot 命令构造宏分析
- uboot 命令分析(二)
- uboot命令分析
- uboot-命令实现分析
- uboot命令分析+实现
- uboot的命令分析
- uboot笔记:uboot命令分析+实现
- uboot之bootm命令分析
- uboot 命令分析(一) — bootm
- uboot命令解释与运行分析
- uboot命令解释与运行分析
- uboot 命令分析(一) — bootm
- uboot 命令分析(一) — bootm
- uboot命令解释与运行分析
- uboot命令解释与运行分析
- rt5350 uboot 命令的简单分析
- uboot 命令分析(一) — bootm
- uboot 命令分析(一) — bootm
- 减少页面回流与重绘(Reflow & Repaint)
- 单表60亿记录等大数据场景的MySQL优化和运维之道
- 《从零开始学Swift》学习笔记(Day 8)——小小常量、变量大作用
- SpringMVC配置字符串绑定日期对象
- setOnItemSelectedListener与OnItemClickListener的区别
- uboot 命令构造宏分析
- STL源码剖析 [容器](十四)[stl_set.h]
- CocoaPods 安装和使用
- ArcGIS for Android示例解析之空间查询-----QueryTask
- Android中AsyncTask类与AsyncQueryHandler类的用法
- 子网划分两个例子---经典
- 数组存储在栈中还是堆中
- 通过Intent传递一些二进制数据的方法有哪些?
- 黑马程序员——36,Collections工具类,Arrays工具类,高级for循环,可变参数,静态导入