initcall是內(nèi)核提供的一種掛接機制,利用這種機制可以讓內(nèi)核在特定的 時刻調(diào)用自己,例如,某些驅(qū)動程序就有這種需要 0,相關(guān)設(shè)施 typedef int (*initcall_t)(void); #define __define_initcall(level,fn,id) \ static initcall_t __initcall_##fn##id __attribute_used__ \ __attribute__((__section__(".initcall" level ".init"))) = fn level的合理取值為0-7,0s-7s(2.6.19.2) 數(shù)值小的將排在前面,相同數(shù)值的s排在非s后面 /* * A "pure" initcall has no dependencies on anything else, and purely * initializes variables that couldn't be statically initialized. * * This only exists for built-in code, not for modules. */ #define pure_initcall(fn) __define_initcall("0",fn,1) #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 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) 內(nèi)核調(diào)用鏈 start_kernel -> rest_init -> init -> do_basic_setup -> do_initcalls 1,所有可以initcall的函數(shù)都必須符合下面形式 int foo(void); 2,__define_initcall宏導(dǎo)出函數(shù)到內(nèi)核映像的.initcalln.init段 __define_initcall("1",foo,1)或 core_initcall(foo) 展開后形成如下申明 static initcall_t __initcall_foo1 __attribute_used__ __attribute__((__section__(".initcall1.init"))) = foo; 所有的申明形成一個initcall_t數(shù)組 3,內(nèi)核在do_initcalls函數(shù)中歷遍該數(shù)組 static void __init do_initcalls(void) { ... for (call = __initcall_start; call < __initcall_end; call++) { ... //對啟動參數(shù)initcall_debug的支持 if (initcall_debug) { printk("Calling initcall 0x%p", *call); print_fn_descriptor_symbol(": %s()", (unsigned long) *call); printk("\n"); } result = (*call)(); ... } } 4,驅(qū)動中用到的重要申明module_init(x)實際就是initcall的特化: #define module_init(x) __initcall(x); #define __initcall(fn) device_initcall(fn) #define device_initcall(fn) __define_initcall("6",fn,6) |
|