1。 函数调用的顺序
(gdb) bt
#0 pci_arch_init () at arch/x86/pci/init.c:13#1 0xc1001255 in do_one_initcall (fn=0xc17a3afa <pci_arch_init>) at init/main.c:758
#2 0xc176c963 in do_initcalls (unused=<value optimized out>) at init/main.c:788
#3 do_basic_setup (unused=<value optimized out>) at init/main.c:806
#4 kernel_init (unused=<value optimized out>) at init/main.c:898
#5 0xc100353e in ?? () at arch/x86/kernel/entry_32.S:1009
#6 0x00000000 in ?? ()
static void __init do_initcalls(void)
{
initcall_t *fn;
for (fn = __early_initcall_end; fn < __initcall_end; fn++)
do_one_initcall(*fn);
}
在vmlinux.lds中定义如下
__early_initcall_end = .; *(.initcall0.init) *(.initcall0s.init) *(.initcall1.init) *(.initcall1s.init) *(.initcall2.init) *(.initcall2s.init) *(.initcall3.init) *(.initcall3s.init) *(.initcall4.init) *(.initcall4s.init) *(.initcall5.init) *(.initcall5s.init) *(.initcallrootfs.init) *(.initcall6.init) *(.initcall6s.init) *(.initcall7.init) *(.initcall7s.init) __initcall_end = .
也就是说 do_initcalls函数 将调用所有 放在这些section的代码。
pci_arch_init函数定义为
static __init int pci_arch_init(void)
{
}
arch_initcall(pci_arch_init);
#define arch_initcall(fn) __define_initcall("3",fn,3)
#define __define_initcall(level,fn,id) \
static initcall_t __initcall_##fn##id __used \
__attribute__((__section__(".initcall" level ".init"))) = fn
这个定义也就是在 .initcall3.init这个section中定义了 __initcall_pci_arch_init_init3 函数指针,其值为 pci_arch_init.