Как 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 ответ

Решение

(Я человек, который написал соответствующий код.)

Скрипт компоновщика дает указание компоновщику упорядочить разделы ".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, используется для heap_init_fn в malloc.c; 04=INIT_NORMAL, используется для smbios smbios_settings.c и т. д.).

Макросы __table_start и __table_end в init.c создают массивы нулевой длины, помещенные в.tbl.init_fns.00 и.tbl.init_fns.99; затем они могут использоваться кодом в init.c для определения начала и конца таблицы, которая была создана компоновщиком.

Надеюсь, это поможет!

Майкл

Другие вопросы по тегам