深入剖析u-boot命令结构
来源:互联网 发布:三级分销算法 编辑:程序博客网 时间:2024/05/06 21:23
转自:http://blog.csdn.net/fzu_dianzi/article/details/7165507
一、环境
目标板:mini2440
u-boot版本:u-boot-2009.08
交叉编译器:arm-linux-gcc-4.3.2
操作系统:Linux(Ubuntu-11.10)
二、目的
1、剖析u-boot命令结构
2、通过代码修改,添加u-boot命令
三、
1、
u-boot支持命令行交互,几乎全部的命令都在common/里面定义。以cmd_开头的文件都是命令类文件。如下图所示:
2、执行命令入口
u-boot stage1执行完后,就跳入stage2 的入口start_armboot函数中。该函数主要进行一系列的初始化,然后进入等待用户命令的循环,main_loop()。
- /* main_loop() can return to retry autoboot, if so just run it again. */
- for (;;)
- {
- main_loop ();
- }
在main_loop()里,u-boot获取用户控制台输入,然后调用run_command函数执行命令。
这里不详细的分析run_command[common/Main.c]的处理流程。
执行命令之前肯定有一个校验命令合法性的过程,u-boot是通过find_cmd来查找已注册的合法命令的。
该函数定义在common/command.c
- cmd_tbl_t *find_cmd (const char *cmd)
- {
- int len = &__u_boot_cmd_end - &__u_boot_cmd_start; //计算命令个数
- return find_cmd_tbl(cmd, &__u_boot_cmd_start, len); //查找命令表
- }
cmd_tbl_t
其定义是在include/command.h
- 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 *[]);
- 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 *argv[], char last_char, int maxv, char *cmdv[]);
- #endif
- };
- typedef struct cmd_tbl_s cmd_tbl_t;
cmd_tbl_t定义了u-boot命令的结构信息,包含命令名、参数最多个数及命令的回调函数等
__u_boot_cmd_ start和__u_boot_cmd_end
其定义是在cpu/larm920t/u-boot.lds(不同类型的cpu,位置不同)
- //u_boot_cmd的起始地址__u_boot_cmd_start,止于__u_boot_cmd_end
- //这段区域内存放u-boot所有命令
- __u_boot_cmd_start = .;
- .u_boot_cmd : { *(.u_boot_cmd) }
- __u_boot_cmd_end = .;
我们可以查看u-boot根目录下system.map,便一目了然。
链接文件里u_boot_cmd段合并在一起生成一个大的.u_boot_cmd段,并且用__u_boot_cmd_start与__u_boot_cmd_end两个符号标识这块内存的首尾边界。这样的机制使得用户添加代码不用去修改其core代码。
3、查看u-boot的命令文件内容
如果我们要自定义出一个命令,那么必须了解其他命令是如何构建的。在每个cmd_XXX.c文件里都可以看到类似下面定义的语句。
- U_BOOT_CMD(
- go, CONFIG_SYS_MAXARGS, 1, do_go,
- "start application at address 'addr'",
- "addr [arg ...]\n - start application at address 'addr'\n"
- " passing 'arg' as arguments"
- );
U_BOOT_CMD
U-Boot中每个命令都通过U_BOOT_CMD宏来定义,其定义是在common/command.h
- /*
- 凡是带有__attribute__ ((unused,section (".u_boot_cmd"))属性声明的变量都将被存放在".u_boot_cmd"段中,并且即使该变量没有在代码中显式的使用编译器也不产生警告信息。
- */
- #define Struct_Section __attribute__ ((unused,section (".u_boot_cmd")))
- #ifdef CFG_LONGHELP
- #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}
- //“##”与“#”都是预编译操作符,“##”有字符串连接的功能,“#”表示后面紧接着的是一个字符串
- #else /* no long help info */
- #define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \
- cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage}
参数意义如下:
name:命令名字;
maxargs:最大的参数个数;
rep:命令是否可重复,可重复是指运行一个命令后,下次敲回车即可再次运行;
cmd:对应的函数指针,一般都是do_name;
usage:简短的使用说明;
help:较详细的使用说明;
go命令的定义经过宏展开后如下:
- cmd_tbl_t __u_boot_cmd_go __attribute__ ((unused,section (".u_boot_cmd"))) =
- {
- go, CONFIG_SYS_MAXARGS, 1, do_go,
- "start application at address 'addr'",
- "addr [arg ...]\n - start application at address 'addr'\n"
- " passing 'arg' as arguments"
- }
实质上就是用U_BOOT_CMD宏定义的信息构造了一个cmd_tbl_t类型的结构体。编译器将该结构体放在“u_boot_cmd”段,执行命令时就可以在“u_boot_cmd”段查找到对应的cmd_tbl_t类型结构体。
4、添加自定义命令
1) 在common/创建一个cmd_care.c
- #include <common.h>
- #include <command.h>
- int do_care (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
- {
- printf("Hello world!\n");
- }
- U_BOOT_CMD(
- care, 2, 1, do_care,
- "u-boot command test by care",
- ""
- );
1) 在common/Makefile添加COBJS-y += cmd_care.o
2) 对u-boot进行编译
3) 结果
编译成功后,查看System.map
证明该命令已经成功添加。
将u-boot.bin烧写到flash,输入我们自定义的命令care
- 深入剖析u-boot命令结构
- 深入剖析u-boot命令结构
- 深入剖析u-boot代码typedef int (init_fnc_t) (void)
- 深入理解 u-boot
- U-boot内存结构。
- U-boot目录结构
- U-Boot源码结构
- u-boot源码结构
- u-boot总体结构
- U-Boot 源码结构
- U-Boot目录结构
- u-boot的boot命令
- 常用U-Boot命令
- U-Boot命令手册
- u-boot 命令
- U-Boot命令手册
- 添加u-boot命令
- U-boot命令(部分)
- Linux下的TCP通信
- 如果一个人,就这样生活
- 一些链接
- CF-60D - Savior(并查集+数论)
- 如果一个人,就这样生活
- 深入剖析u-boot命令结构
- #思考#如何成长?
- jade使用语法
- 2001. Scavenger Hunt
- 如果一个人,就这样生活
- 高并发问题
- Java 竖线|的转义符 是 "\\|"
- 如果一个人,就这样生活
- 手把手教你ARC——ARC入门和使用