iPXE如何在不调用其名称的情况下执行函数

时间:2013-05-15 10:39:31

标签: c ipxe

main.c中,它会调用 initialize() startup()。在init.c中的每个函数内部,它遍历一个包含已注册函数的表并调用它们:

void startup ( void ) {
    struct startup_fn *startup_fn;

    if ( started )
        return;

    /* Call registered startup functions */
    for_each_table_entry ( startup_fn, STARTUP_FNS ) {
        if ( startup_fn->startup )
            startup_fn->startup();
    }

    started = 1;
}

根据评论,我不知道注册函数在哪里。

STARTUP_FNS

#define STARTUP_FNS __table ( struct startup_fn, "startup_fns" )

__table

#define __table( type, name ) ( type, name )

__ table 是我可以研究的结果。评论说它“声明了一个链接表”。但它怎么能得到这些功能呢?

table.h中有更多内容,例如 __ table_entry table_start ...此表来自何处?它的参赛作品在哪里?这是什么意思:

#define table_start( table ) __table_entries ( table, 00 )

00在这里意味着什么?

请帮忙。我真的很想了解。感谢。

1 个答案:

答案 0 :(得分:4)

(我是编写相关代码的人。)

链接描述文件指示链接器安排" .tbl。*"按字母顺序排列。 __table_entry等宏用于将结构放入这些部分。理解这一点的最简单方法可能是查看链接器映射,您可以使用例如"制作bin / rtl8139.rom.map":

.tbl.init_fns.00
            0x000000000001784c        0x0 bin/blib.a(init.o)
.tbl.init_fns.01
            0x000000000001784c        0x4 bin/blib.a(malloc.o)
            0x000000000001784c                heap_init_fn
.tbl.init_fns.04
            0x0000000000017850        0x4 bin/blib.a(pxe_call.o)
            0x0000000000017850                pxe_init_fn
.tbl.init_fns.04
            0x0000000000017854        0x4 bin/blib.a(settings.o)
            0x0000000000017854                builtin_init_fn
.tbl.init_fns.04
            0x0000000000017858        0x4 bin/blib.a(smbios_settings.o)
            0x0000000000017858                smbios_init_fn
.tbl.init_fns.04
            0x000000000001785c        0x4 bin/blib.a(process.o)
            0x000000000001785c                process_init_fn
.tbl.init_fns.05
            0x0000000000017860        0x4 bin/blib.a(embedded.o)
            0x0000000000017860                embedded_init_fn
.tbl.init_fns.99
            0x0000000000017864        0x0 bin/blib.a(init.o)

在这里你可以看到各种结构(heap_init_fn,pxe_init_fn,smbios_init_fn)等已经连续放置在最终图像中,按初始化顺序排序(01 = INIT_EARLY,用于malloc.c中的heap_init_fn; 04 = INIT_NORMAL,使用对于smbios_settings中的smbios_init_fn等。)

init.c中的__table_start和__table_end宏产生位于.tbl.init_fns.00和.tbl.init_fns.99中的零长度数组;然后,init.c中的代码可以使用这些来识别链接器构造的表的开始和结束。

希望有所帮助!

迈克尔