//---------------------------kernel/linux/linux/init.h
#define module_init(x) __initcall(x);
#define__initcall(fn) device_initcall(fn)
#define device_initcall(fn) _define_inticall(fn,6)
#define device_initcall_sync(fn) _define_inticall(fn,6s)
#define__define_initcall(level,fn,id) \
static initcall_t __initcall_##fn##id __used \
__attribute__((__section__(".initcall" level ".init"))) =fn
最终我们看到的是module_init的真身:__define_initcall(level,fn,id),仔细推敲这个真身,知道这是个宏,它把传给module_init的函数名组装成以__initcall为前缀的、以6为后缀的函数名,并把这个函数定义到代码段.initcall6.init里面。
追到下面文件:
//--------------------------kernel/include/asm-generic/vmlinux.lds.h
#define INIT_CALLS \
VMLINUX_SYMBOL(__initcall_start) = .; \
*(.initcallearly.init) \
INIT_CALLS_LEVEL(0) \
INIT_CALLS_LEVEL(1) \
INIT_CALLS_LEVEL(2) \
INIT_CALLS_LEVEL(3) \
INIT_CALLS_LEVEL(4) \
INIT_CALLS_LEVEL(5) \
INIT_CALLS_LEVEL(rootfs) \
INIT_CALLS_LEVEL(6) \
INIT_CALLS_LEVEL(7) \
VMLINUX_SYMBOL(__initcall_end) = .;
#define INIT_CALLS_LEVEL(level) \
VMLINUX_SYMBOL(__initcall##level##_start) = .; \
*(.initcall##level##.init) \
*(.initcall##level##s.init)
=====>>>.initcall6.init \ .initcall6s.init
#defineINIT_DATA_SECTION(initsetup_align) \
.init.data : AT(ADDR(.init.data) -LOAD_OFFSET) { \
INIT_DATA \
INIT_SETUP(initsetup_align) \
INIT_CALLS \
CON_INITCALL \
SECURITY_INITCALL \
INIT_RAM_FS \
}
//--------Kernel/arch/um/os-Linux/main.c
Main()->
//--------Kernel/arch/um/kernel/um_arch.c
linux_main()->
//--------Kernel/arch/um/kernel/skas/process.c
start_uml()->start_kernel_proc()->
//--------kernel/init/main.c
start_kernel->rest_init->kernel_init->kernel_init_freeable->do_basic_setup-> do_initcalls
static void __init do_basic_setup(void)
{
cpuset_init_smp();
usermodehelper_init();
shmem_init();
driver_init();
init_irq_proc();
do_ctors();
usermodehelper_enable();
do_initcalls();
random_int_secret_init();
}
由上面函数可以知道,bus注册在module_init执行之前