linux4.14.39include/linux/module.h 中:
#define module_init(x) __initcall(x); #define module_exit(x) __exitcall(x);
linux4.14.39/include/linux/init.h 中:
/ * * __Initcall every name specified in the function pointer is different * / #define __initcall (the Fn) device_initcall (the Fn) / * * Each .c file can only define a module_exit, because all module_exit definitions * of static function pointers are the same name: __ exit_call = Fn * / #define __exitcall (Fn) static exitcall_t __exitcall _ = ## Fn Fn __exit_call
linux4.14.39/include/linux/init.h 中:
#define pure_initcall(fn) __define_initcall(fn, 0) #define core_initcall(fn) __define_initcall(fn, 1) #define core_initcall_sync(fn) __define_initcall(fn, 1s) #define postcore_initcall(fn) __define_initcall(fn, 2) #define postcore_initcall_sync(fn) __define_initcall(fn, 2s) #define arch_initcall(fn) __define_initcall(fn, 3) #define arch_initcall_sync(fn) __define_initcall(fn, 3s) #define subsys_initcall(fn) __define_initcall(fn, 4) #define subsys_initcall_sync(fn) __define_initcall(fn, 4s) #define fs_initcall(fn) __define_initcall(fn, 5) #define fs_initcall_sync(fn) __define_initcall(fn, 5s) #define rootfs_initcall(fn) __define_initcall(fn, rootfs) /* module_init()的等级是6 */ #define device_initcall(fn) __define_initcall(fn, 6) #define device_initcall_sync(fn) __define_initcall(fn, 6s) /* 触摸板驱动中使用这个 late_initcall */ #define late_initcall(fn) __define_initcall(fn, 7) #define late_initcall_sync(fn) __define_initcall(fn, 7s)
do_initcall_level () function is called only in do_initcalls () once, that is to say the seven levels of initcall no one level to do a special treatment, equal treatment, just call the order is different.
Seven levels of initcall are stored in initcall_levels this array, and finished all at once to call in do_initcalls () in.
linux4.14.39/init/main.c:
static initcall_t *initcall_levels[] __initdata = { __initcall0_start, __initcall1_start, __initcall2_start, __initcall3_start, __initcall4_start, __initcall5_start, __initcall6_start, __initcall7_start, __initcall_end, };
static void __init do_initcall_level(int level) { initcall_t *fn; strcpy(initcall_command_line, saved_command_line); /*先解析命令行参数后再执行*/ parse_args(initcall_level_names[level], initcall_command_line, __start___param, __stop___param - __start___param, level, level, NULL, &repair_env_string); for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++) do_one_initcall(*fn); } static void the __init do_initcalls ( void ) { int Level; / * which determines the pure / arch / late_initcall () like sequence, the smaller is called first * / for (Level = 0 ; Level <ARRAY_SIZE (initcall_levels) - . 1 ; Level ++ ) do_initcall_level (Level); }
to sum up
1. a .c file can have only one module_exit (it can only have a corresponding module_init).
2. initcall Level module_init is 6 .
3.7 rating initcall are processed together, just called different order.