u-boot分析 七 (添加u-boot命令,学习u-boot命令实现原理)

来源:互联网 发布:帝国cms模板游戏 编辑:程序博客网 时间:2024/05/27 20:13

u-boot分析 七

(添加u-boot命令,学习u-boot命令实现原理)



本文目标:

理解u-boot命令的实现原理。


上一篇文章分析了u-boot是如何启动kernel的,其中就涉及到bootm命令,考虑到文章主题需要,当时并没有对bootm命令做过多的解释。然而,u-boot命令行又是u-boot及其重要的一部分。这篇文章,我们就通过实战来理解u-boot命令的实现原理。

我们要做的很简单,就是添加一条uboot command,希望在开发板上,uboot命令行中输入itxiebo时,能够从串口打印出一句log。


一、具体实现步骤:

  1. 在./common文件夹下新建cmd_itxiebo.c,并在此文件中添加如下内容
#include <common.h>#include <command.h>static int do_itxiebo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]){    printf("do_itxiebo command is ready now!");    return 0;}U_BOOT_CMD(    itxiebo,    2,  0,  do_itxiebo,    "itxiebo - this is a itxiebo command, do nothing",    "- this is a itxiebo command, do nothing");

2.在./common/Makefile中添加:

obj-y += cmd_itxiebo.o

3.在linux环境下,重新编译u-boot,得到u-boot.bin,并升级到自己的开发板中(如果你没有开发板,没有关系,你只需要明白我们要在开发板中验证自己添加的命令itxiebo)

4.升级完后,在开发板启动内核之前,按space键进入u-boot命令行模式。
这里写图片描述

5.在串口终端中输入help命令,回车,可以发现itxiebo命令行已经添加成功。
这里写图片描述

6.在串口终端中输入itxiebo命令,回车执行该命令,发现我们添加的打印log,可以正确打印出来:
这里写图片描述


二、命令原理分析

实战见效果了,我们继续分析。不难发现,只要能搞清上面代码中的“U_BOOT_CMD”,就能弄明白uboot命令实现原理。

U_BOOT_CMD格式如下:

U_BOOT_CMD(_name, _maxargs, _rep, _cmd, _usage, _help)

其中,各个参数解释如下:

参数名 说明 _name 命令名,非字符串,但在U_BOOT_CMD中用“#”符号转化为字符串 _maxargs 命令的最大参数个数 _rep 是否自动重复(按Enter键是否会重复执行) _cmd 该命令对应的响应函数 _usage 简短的使用说明(字符串) _help 较详细的使用说明(字符串)

说明:
在内存中保存命令的help字段会占用一定的内存,通过配置U-Boot可以选择是否保存help字段。若在include/configs/s5p4418_urbetter.h 中定义了CONFIG_SYS_LONGHELP宏,则在U-Boot中使用help命令查看某个命令的帮助信息时将显示_usage和_help字段的内容,否则就只显示usage字段的内容,而不显示_help字段的内容。

另外,在include/command.h中,对U_BOOT_CMD的define 如下:

#define ll_entry_declare(_type, _name, _list)               \    _type _u_boot_list_2_##_list##_2_##_name __aligned(4) __attribute__((unused,    section(".u_boot_list_2_"#_list"_2_"#_name)))#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(_name, _maxargs, _rep, _cmd, _usage, _help)      \    U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, NULL)

最后,同样在include/command.h中定义了一个结构体cmd_tbl_t

这里写图片描述

如此,我们便可以将U_BOOT_COM解析,如下

U_BOOT_CMD(    itxiebo,    2,  0,  do_itxiebo,    "itxiebo - this is a itxiebo command, do nothing",    "- this is a itxiebo command, do nothing");解析为:cmd_tbl_t _u_boot_list_2_do_itxiebo_2_itxiebo __aligned(4) __attribute__((unused,section(".u_boot_list_2_"do_itxiebo"_2_"itxiebo)))

其中,“u_boot_list”,《u-boot分析 三》分析u-boot.lds时解释过。也就是说咱们新增的itxiebo command会被储存在u_boot_list段内。

.u_boot_list : {        KEEP(*(SORT(.u_boot_list*)));        /*.data段结束后,紧接着存放u-boot自有的一些function,例如u-boot command等*/    }

三、itxiebo命令的执行过程:

在U-Boot中输入(串口终端)“itxiebo”命令执行时,U-Boot接收输入的字符串“itxiebo”,传递给run_command()函数。run_command()函数调用common/command.c中实现的find_cmd()函数在u_boot_list段内查找命令,并返回itxiebo命令的cmd_tbl_t结构。然后run_command()函数使用返回的cmd_tbl_t结构中的函数指针调用itxiebo命令的响应函数do_itxiebo,从而完成了命令的执行。


参考:
http://www.cnblogs.com/sdphome/archive/2011/08/19/2146327.html


完事儿。

0 0
原创粉丝点击