1

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" )

__表

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

__table是我可以调查的结束。评论说它“声明一个链接器表”。但是它如何获得功能呢?

table.h 里面还有更多,比如__table_entrytable_start ……这个表是哪里来的?它的条目在哪里?这是什么意思:

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

这里是什么00意思?

请帮忙。我真的很想明白。谢谢。

4

1 回答 1

4

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

链接器脚本指示链接器按字母顺序排列节“.tbl.*”。__table_entry 等宏用于将结构放入这些部分。理解这一点的最简单方法可能是查看链接器映射,您可以使用例如“make 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_init_fn中smbios_settings.c 等)。

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

希望有帮助!

迈克尔

于 2013-05-15T12:11:19.323 回答