linux pci 初始化

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.



你可能感兴趣的:(linux)