ll_entry_declare()在U-Boot中如何工作?

时间:2018-03-21 04:54:14

标签: c u-boot

当U-boot shell想要从linker_list中找到命令时,它会调用以下函数 -

cmd_tbl_t *find_cmd(const char *cmd)
{
         cmd_tbl_t *start = ll_entry_start(cmd_tbl_t, cmd);
         const int len = ll_entry_count(cmd_tbl_t, cmd);
         return find_cmd_tbl(cmd, start, len);
}

要获取指向struct cmd_tbl_t的指针,该指针包含此命令的所有细节,将调用ll_entry_start()。

#define ll_entry_start(_type, _list)                                    
 ({                                                                      
         static char start[0] __aligned(4) __attribute__((unused,        
                 section(".u_boot_list_2_"#_list"_1")));                 
         (_type *)&start;                                                
 })

ll_entry_start返回指向持有命令的struct cmd_tbl_t的开头的指针。

我们无法预测传递给find_cmd()的字符串是什么。

#(stringizing)运算符是一个预处理器指令。它无法在运行时从令牌名称生成字符串。编译器如何为_list可以承担的所有可能的字符串值生成代码?

1 个答案:

答案 0 :(得分:0)

通过使用U_BOOT_CMD宏指定命令来填充命令的链接器生成列表。这是cmd / bootefi.c的一个例子。

U_BOOT_CMD(
        bootefi, 3, 0, do_bootefi,
        "Boots an EFI payload from memory",
        bootefi_help_text
);

链接器为每个命令在u-boot二进制文件中创建一个部分,例如:对于bootefi:.u_boot_list_2_cmd_2_bootefi

您可以使用ll_entry_start和ll_entry_next迭代链接器生成的列表。以下是从lib / efi_selftest / efi_selftest.c获取的示例:

for (test = ll_entry_start(struct efi_unit_test, efi_unit_test);
     test < ll_entry_end(struct efi_unit_test, efi_unit_test); ++test) {
        efi_st_printf("'%s'%s\n", test->name,
                      test->on_request ? " - on request" : "");
}