查看: 2961|回复: 0

[分享] 使用U_BOOT_CMD()自定义uboot命令

[复制链接]

该用户从未签到

723

主题

6382

帖子

0

超级版主

Rank: 8Rank: 8

积分
25469
最后登录
2025-9-8
发表于 2021-11-22 13:59:48 | 显示全部楼层 |阅读模式
本帖最后由 小恩GG 于 2021-11-22 13:59 编辑

如果要添加自己的uboot命令必须要使用U_BOOT_CMD()这个宏。

U_BOOT_CMD()宏定义
typedef struct cmd_tbl_s        cmd_tbl_t;


#define U_BOOT_CMD(_name, _maxargs, _rep, _cmd, _usage, _help)                \
        U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, NULL) \


#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_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd,_usage, _help, _comp)                        \
                {
                        #_name,
                        _maxargs,         
                        _rep ? cmd_always_repeatable : cmd_never_repeatable,         
                        _cmd,
                        _usage,
                        _CMD_HELP(_help)
                        _CMD_COMPLETE(_comp)
                }


#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)))
_name:uboot中命令的名字

_maxargs:最多几个args

_rep:是否自动重复(按Enter键是否会重复执行)

_cmd:我们自己写的函数

_usage:函数的用途说明,比如“检测hdmi功能”

_help:较详细的使用说明(字符串)

/**
* ll_entry_declare() - Declare linker-generated array entry
* @_type:        Data type of the entry
* @_name:        Name of the entry
* @_list:        name of the list. Should contain only characters allowed
*                in a C variable name!
*
* This macro declares a variable that is placed into a linker-generated
* array. This is a basic building block for more advanced use of linker-
* generated arrays. The user is expected to build their own macro wrapper
* around this one.
*
* A variable declared using this macro must be compile-time initialized.
*
* Special precaution must be made when using this macro:
*
* 1) The _type must not contain the "static" keyword, otherwise the
*    entry is generated and can be iterated but is listed in the map
*    file and cannot be retrieved by name.
*
* 2) In case a section is declared that contains some array elements AND
*    a subsection of this section is declared and contains some elements,
*    it is imperative that the elements are of the same type.
*
* 3) In case an outer section is declared that contains some array elements
*    AND an inner subsection of this section is declared and contains some
*    elements, then when traversing the outer section, even the elements of
*    the inner sections are present in the array.
*
* Example:
*
* ::
*
*   ll_entry_declare(struct my_sub_cmd, my_sub_cmd, cmd_sub) = {
*           .x = 3,
*           .y = 4,
*   };
*/
#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)
以fastboot为例

U_BOOT_CMD(
        fastboot,
        CONFIG_SYS_MAXARGS,
        1,
        do_fastboot,
        "run as a fastboot usb or udp device",
        fastboot_help_text
);



U_BOOT_CMD(fastboot, CONFIG_SYS_MAXARGS, 1, do_fastboot,"run as a fastboot usb or udp device", fastboot_help_text);
====展开得到====>


U_BOOT_CMD_COMPLETE(fastboot, CONFIG_SYS_MAXARGS, 1, do_fastboot,"run as a fastboot usb or udp device", fastboot_help_text, NULL)
====展开得到====>


ll_entry_declare(cmd_tbl_t, fastboot, cmd) =
                {
                        #fastboot,
                        64,                                         // #define CONFIG_SYS_MAXARGS      64  /* max command args */
                        cmd_always_repeatable,         
                        do_fastboot,
                        "run as a fastboot usb or udp device",
                        fastboot_help_text,
                        NULL
                }
====展开得到====>


_type _u_boot_list_2_cmd_2_fastboot __aligned(4) __attribute__((unused,        section(".u_boot_list_2_cmd_2_fastboot")))=
{
        #fastboot,
        64,                                         // #define CONFIG_SYS_MAXARGS      64  /* max command args */
        cmd_always_repeatable,         
        do_fastboot,
        "run as a fastboot usb or udp device",
        fastboot_help_text,
        NULL
}
可以看出,通过`U_BOOT_CMD`宏控就生成了一个`_u_boot_list_2_cmd_2_fastboot` 类型的结构体。

凡是带有`attribute ((unused,section (“.u_boot_list”))`属性声明的变量都将被存放在`.u_boot_list`段中,并且即使该变量没有在代码中显式的使用编译器也不产生警告信息。

\arch\arm\cpu\u-boot.lds
        . = .;


        . = ALIGN(4);
        .u_boot_list : {
                KEEP(*(SORT(.u_boot_list*)));
        }


        . = ALIGN(4)
这表明,凡是以`u_boot_list`开头的都会被放在 `.u_boot_list`段中。至此,我们就将 fastboot 命令相关信息在编译阶段就存储在了 `.u_boot_list` 段中。

在编译中, `.u_boot_list` 字段就会和 `.text . data` 一样被打包进uboot bin中。

# limit ourselves to the sections we want in the .bin.
ifdef CONFIG_ARM64
OBJCOPYFLAGS += -j .text -j .image -j .secure_text -j .secure_data -j .rodata -j .data \
                -j .u_boot_list -j .rela.dyn -j .got -j .got.plt \
                -j .binman_sym_table -j .text_rest
else
OBJCOPYFLAGS += -j .text -j .secure_text -j .image -j .secure_data -j .rodata -j .hash \
                -j .data -j .got -j .got.plt -j .u_boot_list -j .rel.dyn \
                -j .binman_sym_table -j .text_rest
endif
命令调用过程
un_command common/cli.c
         cli_simple_run_command        common/cli_simple.c
                cli_simple_parse_line                                 分析参数
                cmd_process                common/command.c       
                        find_cmd                                                 根据name查找命令,在section .u_boot_list_2_cmd_1和.u_boot_list_2_cmd_3 之间查找
                        cmd_call                                                执行命令




回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条

Archiver|手机版|小黑屋|恩智浦技术社区

GMT+8, 2025-9-9 05:25 , Processed in 0.082695 second(s), 19 queries , MemCache On.

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

快速回复 返回顶部 返回列表