2013-05-15 2 views
1

В main.c, он вызывает Initialize() и запуска(). Внутри каждой из этих функций в init.c, он перебирает в таблице, которая содержит зарегистрированные функции и называет их:Как iPXE выполняет функции, не вызывая его имена

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 значит здесь?

Пожалуйста, помогите. Я действительно хочу понять. Благодарю.

ответ

4

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

Компоновщик сценарий предписывает компоновщика организовать секции «.tbl. *» В алфавитном порядке. Макросы __table_entry и т. Д. Используются для размещения структур в этих разделах. Самый простой способ понять это, вероятно, - это посмотреть на карту компоновщика, которую вы можете создать, например, «Сделать бен/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_fn в smbios_settings.c и т. Д.).

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

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

Michael

+1

Кстати, макрос __table() является хорошим примером того, как определять и использовать векторнозначные макросы. –