initcall_entry_t *fn; parse_args(initcall_level_names[level], command_line, __start___param, __stop___param - __start___param, level, level, NULL, ignore_unknown_bootoption); trace_initcall_level(initcall_level_names[level]); for (fn = initcall_levels[level]; fn < initcall_levels[...
{ initcall_entry_t *fn; parse_args(initcall_level_names[level], command_line, __start___param, __stop___param - __start___param,level,level,NULL, ignore_unknown_bootoption); trace_initcall_level(initcall_level_names[level]);for(fn = initcall_levels[level]; fn < initcall_levels[level...
static void __init do_initcalls(void){int level;size_t len = strlen(saved_command_line) + 1;char *command_line;command_line = kzalloc(len, GFP_KERNEL);if (!command_line)panic("%s: Failed to allocate %zu bytes\n", __func__, len);//遍历所有等级的initcall,level变量对应等级for (leve...
NULL, &repair_env_string);trace_initcall_level(initcall_level_names[level]); for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++)do_one_initcall(initcall_from_entry(fn)); } 根据下表,分别调用 do_one_initcall 来执行每一个 initcall。 staticinitcall_entry_t*initcall_leve...
staticvoid__initdo_initcall_level(int level,char*command_line){initcall_entry_t*fn;parse_args(initcall_level_names[level],command_line,__start___param,__stop___param-__start___param,level,level,NULL,ignore_unknown_bootoption);trace_initcall_level(initcall_level_names[level]);for(fn=initcal...
initcall_entry_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); ...
initcall_entry_t *fn; trace_initcall_level("early"); for (fn = __initcall_start; fn < __initcall0_start; fn++) do_one_initcall(initcall_from_entry(fn)); } 我们对do_initcalls分析,这里是大部分initcall的调用 static initcall_entry_t *initcall_levels[] __initdata = { ...
staticinitcall_entry_t*initcall_levels[] __initdata = { __initcall0_start, __initcall1_start, __initcall2_start, __initcall3_start, __initcall4_start, __initcall5_start, __initcall6_start, __initcall7_start, __initcall_end,
在实际执行时,内核必须知道xxx_initcall section所在的位置,而在include/asm-generic/vmlinux.lds.h中将xxx_start和.initcall*.init链接到了一起,这样的话,do_initcalls()遍历不同ID的initcall时,基于xxx_start便可以找到想对应的.initcall entry,然后循环遍历里面的各个initcalls。
typedef void (*exitcall_t)(void); extern initcall_t __con_initcall_start[], __con_initcall_end[]; extern initcall_t __security_initcall_start[], __security_initcall_end[]; #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS typedef int initcall_entry_t; static inline initcall_t initcall_from_en...