initcall_levels
initcall_levels
可以写成如下形式
initcall_t __initcall6_start[] = {
...
__initcall_w6,//module_init(w)
__initcall_x6,//module_init(x)
__initcall_y6,//module_init(y)
...
};
static initcall_t *initcall_levels[] __initdata = {
...
__initcall5_start,
__initcall6_start,
__initcall7_start,
__initcall_end,
};
static void __init do_basic_setup(void)
{
...
do_initcalls();
}
static void __init do_initcalls(void)
{
int level;
//__initcall6_start对应level6
//调用所有level的module init函数
for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++)
do_initcall_level(level);
}
static void __init do_initcall_level(int level)
{
...
//调用一个level的所有moduel init函数
for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++)
do_one_initcall(*fn);
}
int __init_or_module do_one_initcall(initcall_t fn)
{
...
int ret;
...
//如果是module_init(x),这里就是ret=x();
ret = fn();
...
return ret;
}
从名字很容易看出来,do_basic_setup
是一个开机时被调用的函数,这个函数会依次对所有level做“initcall”,会把level6的moduel_init定义的函数都调用一遍。do_initcalls
是遍历所有level,do_initcall_level
是遍历一个level的所有函数,do_one_initcall
就是调用一个函数。
module exit情况又如何?