#yyds干货盘点#使用U_BOOT_CMD()自定义uboot命令
Posted MuggleZero
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#yyds干货盘点#使用U_BOOT_CMD()自定义uboot命令相关的知识,希望对你有一定的参考价值。
首先引入command相关的头文件:
如果要添加自己的uboot命令必须要使用U_BOOT_CMD()这个宏。以hdmi检测功能为例:
U_BOOT_CMD(hdmidet, 1, 1, do_hdmidet,
"detect HDMI monitor",
""
);
U_BOOT_CMD()宏定义
typedef struct cmd_tbl_s cmd_tbl_t;
_maxargs,
_rep ? cmd_always_repeatable : cmd_never_repeatable,
_cmd,
_usage,
_CMD_HELP(_help)
_CMD_COMPLETE(_comp)
}
_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,
* };
*/
以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) =
{
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")))=
{
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
段中,并且即使该变量没有在代码中显式的使用编译器也不产生警告信息。
asm
\\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 #yyds干货盘点#自适应布局方案#yyds干货盘点#hyperf自定义验证与格式化输出验证信息
Flutter 专题29 图解自定义底部状态栏 ACEBottomNavigationBar #yyds干货盘点#