В main.c он вызывает < strong> initialize () и startup () . Внутри каждой из этих функций в init.c < / a>, он перебирает таблицу, содержащую зарегистрированные функции, и вызывает их:

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
Amumu 15 Май 2013 в 14:39

1 ответ

Лучший ответ

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

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

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

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

Майкл

4
Michael Brown 15 Май 2013 в 16:11
1
Между прочим, макрос __table () - хороший пример того, как определять и использовать векторные макросы.
 – 
Michael Brown
16 Май 2013 в 02:48