1、代码位置

(1)uboot命令体系的实现代码在uboot/common/cmd_xxx.c中。有若干个.c文件和命令体系有关。(还有command.c  main.c也是和命令有关的)

2、传参方式

命令参数以argc&argv传给函数
(1)有些uboot的命令还支持传递参数。也就是说命令背后对应的函数接收的参数列表中有argc和argv,然后命令体系会把我们执行命令时的命令+参数(md 30000000 10)以argc(3)和argv(argv[0]=md, argv[1]=30000000 argv[2]=10)的方式传递给执行命令的函数。

3、uboot命令解析和执行过程分析

(1)uboot启动的第二阶段,在初始化了所有该初始化的东西后,进入了一个死循环,死循环的循环体就是main_loop。
(2)main_loop函数执行一遍,就是一个获取命令、解析命令、执行命令的过程。
(3)run_command函数就是用来执行命令的函数。

关键点分析
(1)控制台命令获取
(2)命令解析。parse_line函数把"md 30000000 10"解析成argv[0]=md, argv[1]=30000000 argv[2]=10;
(3)命令集中查找命令。find_cmd(argv[0])函数去uboot的命令集合当中搜索有没有argv[0]这个命令,
(4)执行命令。最后用函数指针的方式调用执行了对应函数。

3、存储方式

uboot没有使用数组或者链表,而是使用了一种新的方式来实现这个功能。指定起始地址与结束地址,将命令依次排布(在链接脚本中实现。)

__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;

命令结构体cmd_tbl_t

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 CFG_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;

(1)name:命令名称,字符串格式。
(2)maxargs:命令最多可以接收多少个参数
(3)repeatable:指示这个命令是否可重复执行。重复执行是uboot命令行的一种工作机制,就是直接按回车则执行上一条执行的命令。
(4)cmd:函数指针,命令对应的函数的函数指针,将来执行这个命令的函数时使用这个函数指针来调用。
(5)usage:命令的短帮助信息。对命令的简单描述。
(6)help:命令的长帮助信息。细节的帮助信息。
(7)complete:函数指针,指向这个命令的自动补全的函数。
总结:uboot的命令体系在工作时,一个命令对应一个cmd_tbl_t结构体的一个实例,然后uboot支持多少个命令,就需要多少个结构体实例。uboot的命令体系把这些结构体实例管理起来,当用户输入了一个命令时,uboot会去这些结构体实例中查找(查找方法和存储管理的方法有关)。如果找到则执行命令,如果未找到则提示命令未知。

4、uboot实现命令管理的思路

(1)填充1个结构体实例构成一个命令
(2)给命令结构体实例附加特定段属性(用户自定义段),链接时将带有该段属性的内容链接在一起排列(挨着的,不会夹杂其他东西,也不会丢掉一个带有这种段属性的,但是顺序是乱序的)。
(3)uboot重定位时将该段整体加载到DDR中。加载到DDR中的uboot镜像中带有特定段属性的这一段其实就是命令结构体的集合,有点像一个命令结构体数组。
(4)段起始地址和结束地址(链接地址、定义在u-boot.lds中)决定了这些命令集的开始和结束地址。

uboot命令定义具体实现分析
(1)U_BOOT_CMD宏基本分析
这个宏定义在uboot/common/command.h中。

U_BOOT_CMD(
version, , , do_version,
"version - print monitor version\n",
NULL
);
这个宏替换后变成:
cmd_tbl_t __u_boot_cmd_version __attribute__ ((unused,section (".u_boot_cmd"))) = {#name, maxargs, rep, cmd, usage, help}

总结:这个U_BOOT_CMD宏的理解,关键在于结构体变量的名字和段属性。名字使用##作为连字符,附加了用户自定义段属性,以保证链接时将这些数据结构链接在一起排布。

5、.uboot中增加自定义命令

1、在已有的c文件中直接添加命令
(1)在uboot/common/command.c中添加一个命令,叫:mycmd
(2)在已有的.c文件中添加命令比较简单,直接使用U_BOOT_CMD宏即可添加命令,给命令提供一个do_xxx的对应的函数这个命令就齐活了。
(3)添加完成后要重新编译工程(make distclean; make x210_sd_config; make),然后烧录新的uboot去运行即可体验新命令。
(4)还可以在函数中使用argc和argv来验证传参。

2、自建一个c文件并添加命令
(1)在uboot/common目录下新建一个命令文件,叫cmd_aston.c(对应的命令名就叫aston,对应的函数就叫do_aston函数),然后在c文件中添加命令对应的U_BOOT_CMD宏和函数。注意头文件包含不要漏掉。
(2)在uboot/common/Makefile中添加上aston.o,目的是让Make在编译时能否把cmd_aston.c编译链接进去。
(3)重新编译烧录。重新编译步骤是:make distclean; make x210_sd_config; make

3、体会:uboot命令体系的优点
(1)uboot的命令体系本身稍微复杂,但是他写好之后就不用动了。我们后面在移植uboot时也不会去动uboot的命令体系。我们最多就是向uboot中去添加命令,就像本节课所做的这样。
(2)向uboot中添加命令非常简单。

#include <common.h>
#include <command.h> int
do_mycmd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
extern char version_string[];
printf ("\n%s\n", version_string);
return ;
} U_BOOT_CMD(
mycmd, , , do_mycmd,
"version - print monitor version\n",
NULL
);

uboot 的命令体系的更多相关文章

  1. uboot中的命令体系

    一.uboot的命令体系介绍以及实例分析: U-Boot 的命令实现大多在 common 目录下.在该目录下命令的代码文件都是以“ cmd_”开头的,如下图所示: 其中每一个文件都是一个命令实现的代码 ...

  2. (二)ubuntu学习前传—uboot常见命令

    1.uboot命令类似于linux行缓冲命令行,当我们向终端命令行输入命令的时候,这些命令没有立即被系统识别,而是被缓冲到一个缓存区(也就是系统认为我换没有输入完),当我们按下回车键(换行)后,系统就 ...

  3. UBoot常用命令手册

    UBoot常用命令手册 U-Boot还提供了更加详细的命令帮助,可以通过”?”显示支持的命令列表,通过help [CommandName]命令还可以查看每个命令的参数说明. 1.bootm bootm ...

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

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

  5. UBOOT添加命令的执行流程

    BootLoader(引导装载程序)是嵌入式系统软件开发的第一个环节,它把操作系统和硬件平台衔接在一起,对于嵌入式系统的后续软件开发十分重要,在整个开发中也占有相当大的比例.U-BOOT是当前比较流行 ...

  6. u-boot(四)命令实现

    目录 u-boot(四)命令实现 分析run_command 小结 自定义一个命令 代码 makefile title: u-boot(四)命令实现 tags: linux date: 2018-09 ...

  7. uboot 添加自定义命令

    ref : https://www.cnblogs.com/FREMONT/p/9824226.html 1.添加命令 1.1在common目录下,新建一个cmd_xx.c, 需要添加的命令格式为: ...

  8. uboot常用命令

    一. 常用简单命令 1.1. help命令 a. 帮助查看其他命令的使用方法,类型linux下man b. 示例: help help x210 # help help help [command . ...

  9. uboot相关命令及用法

    进入uboot时,在命令行上敲“?” ,回车就会打印出在uboot里可用的命令: #??       - alias for 'help'base    - print or set address ...

随机推荐

  1. 开源自动驾驶仿真平台 AirSim (2) - 编译 AirSim

    AirSim 的官方 Github: https://github.com/Microsoft/AirSim 对于 Unreal Engine 来说,AirSim 其实是作为一个插件存在,说白了就是把 ...

  2. LeetCode 135——分发糖果

    1. 题目 2. 解答 初始化左序奖赏全为 1,从左往右遍历,如果右边的人评分比左边高,右边奖赏比左边奖赏增 1. 初始化右序奖赏全为 1,从右往左遍历,如果左边的人评分比右边高,左边奖赏比右边奖赏增 ...

  3. 《机器学习实战》笔记——决策树(ID3)

    现在要介绍的是ID3决策树算法,只适用于标称型数据,不适用于数值型数据. 决策树学习算法最大的优点是,他可以自学习,在学习过程中,不需要使用者了解过多的背景知识.领域知识,只需要对训练实例进行较好的标 ...

  4. oracle常用函数总结

    Oracle常用函数总结 ---oracle常用函数-----一.数值型常用函数----取整数--select floor(10.1) from dual;--将n四舍五入,保留小数点后m位(默认情况 ...

  5. 【转载】java byte转十六进制

    public static String bytes2HexString(byte[] b) { String ret = ""; for (int i = 0; i < b ...

  6. POJ 3525/UVA 1396 Most Distant Point from the Sea(二分+半平面交)

    Description The main land of Japan called Honshu is an island surrounded by the sea. In such an isla ...

  7. POJ 3308 Paratroopers(最大流最小割の最小点权覆盖)

    Description It is year 2500 A.D. and there is a terrible war between the forces of the Earth and the ...

  8. POJ 1815 Friendship(最大流最小割の字典序割点集)

    Description In modern society, each person has his own friends. Since all the people are very busy, ...

  9. Prime Matrix(暴力出奇迹)

    Description You've got an n × m matrix. The matrix consists of integers. In one move, you can apply ...

  10. Alpha 冲刺报告(3/10)

    Alpha 冲刺报告 队名:洛基小队 峻雄(组长) 已完成:开始编写角色的移动脚本 明日计划:继续学习并进行脚本编写 剩余任务:物品背包交互代码 困难:如何把各个模块的脚本整合起来 --------- ...