Linux系統使用兩種方式去加載系統中的模塊:動態和靜態。linux
靜態加載:將全部模塊的程序編譯到Linux內核中,由do_initcall函數加載函數
核心進程(/init/main.c)kernel_init do_basic_setup() do_initcalls()該函數中會將在__initcall_start和__initcall_end之間定 義的各個模塊依次加載。那麼在__initcall_start 和 __initcall_end之間都有些什麼呢?post
找到/arch/powerpc/kernel/vmlinux.lds文件,找到.initcall.init段:spa
.initcall.init : { __initcall_start = .; *(.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 = .; }
也就是說14個宏有優先級:0>1>1s>2>2s………>7>7scode
#define pure_initcall(fn) __define_initcall("0",fn,0) #define core_initcall(fn) __define_initcall("1",fn,1) #define core_initcall_sync(fn) __define_initcall("1s",fn,1s) #define postcore_initcall(fn) __define_initcall("2",fn,2) #define postcore_initcall_sync(fn) __define_initcall("2s",fn,2s) #define arch_initcall(fn) __define_initcall("3",fn,3) #define arch_initcall_sync(fn) __define_initcall("3s",fn,3s) #define subsys_initcall(fn) __define_initcall("4",fn,4) #define subsys_initcall_sync(fn) __define_initcall("4s",fn,4s) #define fs_initcall(fn) __define_initcall("5",fn,5) #define fs_initcall_sync(fn) __define_initcall("5s",fn,5s) #define rootfs_initcall(fn) __define_initcall("rootfs",fn,rootfs) #define device_initcall(fn) __define_initcall("6",fn,6) #define device_initcall_sync(fn) __define_initcall("6s",fn,6s) #define late_initcall(fn) __define_initcall("7",fn,7) #define late_initcall_sync(fn) __define_initcall("7s",fn,7s)
module_init = device_initcallblog
動態加載:模塊初始化函數都用module_init(fn)聲明的話,若是一個子系統下有兩個module_init(fn),則這兩個初始化函數的執行順序只跟連接順序有關。排序
即,此時順序與Makefile文件中的排序有關。進程
obj-y += '先調用module_init'/ obj-y += '後調用module_init'/