In main.c, it calls initialize() and startup(). Inside each of these functions in init.c, it loops through a table that contains the registered functions and calls them:
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;
}
I don't know where the registered functions are, according to the comment.
#define STARTUP_FNS __table ( struct startup_fn, "startup_fns" )
#define __table( type, name ) ( type, name )
__table is the end of what I can look into. The comment says that it "Declare a linker table". But how can it get the functions?
There are more in table.h, such as __table_entry, table_start... where does this table come from? Where are its entries? what does it mean by:
#define table_start( table ) __table_entries ( table, 00 )
What does 00
mean here?
Please help. I really want to understand. Thanks.
(I'm the person who wrote the code in question.)
The linker script instructs the linker to arrange sections ".tbl.*" in alphabetical order. The __table_entry etc macros are used to place structures into these sections. The easiest way to understand this is probably to look at the linker map, which you can produce using e.g. "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)
Here you can see the various structures (heap_init_fn, pxe_init_fn, smbios_init_fn) etc. have been placed consecutively in the final image, sorted by initialisation order (01=INIT_EARLY, used for heap_init_fn in malloc.c; 04=INIT_NORMAL, used for smbios_init_fn in smbios_settings.c etc).
The __table_start and __table_end macros in init.c produce zero-length arrays placed in .tbl.init_fns.00 and .tbl.init_fns.99; these can then be used by the code in init.c to identify the start and end of the table that has been constructed by the linker.
Hope that helps!
Michael