Linux确实根据需要为我们提供了7种不同的初始化级别供您选择。我想知道init级别如何确定要调用哪个模块的init。例如,驱动程序A和驱动程序B都在fs_initcall级别定义了模块初始化。 Linux如何确定首先要呼叫哪一个。
答案 0 :(得分:0)
对于同一级别,它由Makefile顺序确定,例如,在我的驱动程序/输入/触摸屏/ Makefile中:
obj-$(CONFIG_TOUCHSCREEN_IT7259_I2C) += it7259_ts_i2c.o
obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_touch/
it7259将首先被调用。
您可以在out / system.map中找到详细顺序:
c116ae80 T __initcall6_start
...
c116b278 t __initcall_it7259_ts_driver_init6
c116b27c t __initcall_fts_ts_init6
...
c116b6a4 T __initcall7_start
如果您更改Makefile中的顺序,请确保清除“ out”文件夹,然后重新生成,然后system.map将以新顺序进行更新。
更多信息:
以下定义将用于创建.init.data节:
静态initcall_t initcall _ ## fn ## id __已使用\ __attribute ((( section (“。initcall” level“ .init”))))= fn
每个__initcall(x)将成为.init.data节中的一项,例如:
c116b27c t __initcall_fts_ts_init6
启动时的初始调用流程: start_kernel-> rest_init-> kernel_init-> do_basic_setup-> do_initcalls
静态void __init do_initcalls(void) { 诠释级别;
for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++)
do_initcall_level(level);
}
静态void __init do_initcall_level(int级别) { extern const struct kernel_param __start ___ param [],__stop ___ param []; initcall_t * fn;
strcpy(static_command_line, saved_command_line);
parse_args(initcall_level_names[level],
static_command_line, __start___param,
__stop___param - __start___param,
level, level,
repair_env_string);
for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++)
do_one_initcall(*fn);
}
静态initcall_t * initcall_levels [] __initdata = { __initcall0_start, __initcall1_start, __initcall2_start, __initcall3_start, __initcall4_start, __initcall5_start, __initcall6_start, __initcall7_start, __initcall_end, };
在vmlinux.lds中,它将转到.init.data节中的地址。