mod->init什么时候赋值
When does mod->init be assigned
当Linux内核用insmod加载新的module时,它将调用
finit_module
do_init_module
do_one_initcall
然后调用module中定义的初始化函数。
static noinline int do_init_module(struct module *mod)
{
int ret = 0;
struct mod_initfree *freeinit;
freeinit = kmalloc(sizeof(*freeinit), GFP_KERNEL);
if (!freeinit) {
ret = -ENOMEM;
goto fail;
}
freeinit->module_init = mod->init_layout.base;
/*
* We want to find out whether @mod uses async during init. Clear
* PF_USED_ASYNC. async_schedule*() will set it.
*/
current->flags &= ~PF_USED_ASYNC;
do_mod_ctors(mod);
/* Start the module */
if (mod->init != NULL)
ret = do_one_initcall(mod->init);
...
}
但是搜索了linux内核的所有代码后,我没有找到mod->init assigned的地方,谁能帮帮我?
提前致谢。
mod->init
和 mod->exit
的值来自模块 .ko 文件的 .gnu.linkonce.this_module
部分中包含的 struct module __this_module
变量。内核假设这个变量在节的开头,实际上它是节中的只有变量。
__this_module
变量由 modulename.mod.c 文件中的 C 初始化程序初始化,该文件是在内核构建过程的 MODPOST 阶段生成的. modulename.mod.c 文件中 __this_module
变量的典型定义对于当前内核如下所示:
__visible struct module __this_module
__section(.gnu.linkonce.this_module) = {
.name = KBUILD_MODNAME,
.init = init_module,
#ifdef CONFIG_MODULE_UNLOAD
.exit = cleanup_module,
#endif
.arch = MODULE_ARCH_INIT,
};
finit_module
和 init_module
系统调用处理函数调用 load_module
来完成大部分工作。 load_module
调用 setup_load_info
,它会查找仅包含 __this_module
变量的 .gnu.linkonce.this_module
部分。指向它的临时指针放在 info->mod
中(其中 info
指向 struct load_info
用于保存加载模块的信息)。 load_module
稍后调用 layout_and_allocate
其中 returns 指向 __this_module
变量的指针(实际上是指向 .gnu.linkonce.this_module
部分的指针)在它被复制到它的最终通过 move_module
放置在内核内存中。在 load_module
调用 apply_relocations
执行动态链接后,mod->init
和 mod->exit
将具有它们的最终值(忽略内核 5.13 中 CONFIG_CFI_CLANG
的修改)。
请注意,__this_module.init
函数指针始终是指向 init_module
的指针或默认为 null,而 __this_module.exit
函数指针始终是指向 [=40 的指针=] 或默认为空。 (大多数模块源代码使用 module_init(initfn)
和 module_exit(exitfn)
宏来创建这些函数,但它们可以显式定义。)
当Linux内核用insmod加载新的module时,它将调用
finit_module
do_init_module
do_one_initcall
然后调用module中定义的初始化函数。
static noinline int do_init_module(struct module *mod)
{
int ret = 0;
struct mod_initfree *freeinit;
freeinit = kmalloc(sizeof(*freeinit), GFP_KERNEL);
if (!freeinit) {
ret = -ENOMEM;
goto fail;
}
freeinit->module_init = mod->init_layout.base;
/*
* We want to find out whether @mod uses async during init. Clear
* PF_USED_ASYNC. async_schedule*() will set it.
*/
current->flags &= ~PF_USED_ASYNC;
do_mod_ctors(mod);
/* Start the module */
if (mod->init != NULL)
ret = do_one_initcall(mod->init);
...
}
但是搜索了linux内核的所有代码后,我没有找到mod->init assigned的地方,谁能帮帮我?
提前致谢。
mod->init
和 mod->exit
的值来自模块 .ko 文件的 .gnu.linkonce.this_module
部分中包含的 struct module __this_module
变量。内核假设这个变量在节的开头,实际上它是节中的只有变量。
__this_module
变量由 modulename.mod.c 文件中的 C 初始化程序初始化,该文件是在内核构建过程的 MODPOST 阶段生成的. modulename.mod.c 文件中 __this_module
变量的典型定义对于当前内核如下所示:
__visible struct module __this_module
__section(.gnu.linkonce.this_module) = {
.name = KBUILD_MODNAME,
.init = init_module,
#ifdef CONFIG_MODULE_UNLOAD
.exit = cleanup_module,
#endif
.arch = MODULE_ARCH_INIT,
};
finit_module
和 init_module
系统调用处理函数调用 load_module
来完成大部分工作。 load_module
调用 setup_load_info
,它会查找仅包含 __this_module
变量的 .gnu.linkonce.this_module
部分。指向它的临时指针放在 info->mod
中(其中 info
指向 struct load_info
用于保存加载模块的信息)。 load_module
稍后调用 layout_and_allocate
其中 returns 指向 __this_module
变量的指针(实际上是指向 .gnu.linkonce.this_module
部分的指针)在它被复制到它的最终通过 move_module
放置在内核内存中。在 load_module
调用 apply_relocations
执行动态链接后,mod->init
和 mod->exit
将具有它们的最终值(忽略内核 5.13 中 CONFIG_CFI_CLANG
的修改)。
请注意,__this_module.init
函数指针始终是指向 init_module
的指针或默认为 null,而 __this_module.exit
函数指针始终是指向 [=40 的指针=] 或默认为空。 (大多数模块源代码使用 module_init(initfn)
和 module_exit(exitfn)
宏来创建这些函数,但它们可以显式定义。)