initcall 宏阅读笔记
作者:互联网
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中指定的每一个函数指针的名字都是不同的 */ #define __initcall(fn) device_initcall(fn) /* * 每一个.c文件中只能定义一个 module_exit,因为全部module_exit定义 * 的都是static的同名的函数指针:__exit_call = fn */ #define __exitcall(fn) static exitcall_t __exitcall_##fn __exit_call = fn
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() 函数只在 do_initcalls() 中被调用一次,也就是说这七个等级的 initcall 没有任何一个等级做了特殊处理,同等对待,只是调用的先后次序不同而已。
七个等级的 initcall 都被存放在 initcall_levels 这个数组中了,在 do_initcalls() 中一次性全部调用完。
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 __init do_initcalls(void) { int level; /*这决定了pure/arch/late_initcall()等的先后顺序,越小越先被调用*/ for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++) do_initcall_level(level); }
总结
1. 一个.c文件中只能有一个 module_exit(对应的也就只能有一个 module_init)。
2. module_init 的 initcall level 为6。
3. 7个等级的 initcall 是一起被处理的,只是调用的先后顺序不同。
标签:__,level,笔记,start,阅读,initcall,fn,define 来源: https://www.cnblogs.com/hellokitty2/p/11005513.html