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->initmod->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_moduleinit_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->initmod->exit 将具有它们的最终值(忽略内核 5.13 中 CONFIG_CFI_CLANG 的修改)。

请注意,__this_module.init 函数指针始终是指向 init_module 的指针或默认为 null,而 __this_module.exit 函数指针始终是指向 [=40 的指针=] 或默认为空。 (大多数模块源代码使用 module_init(initfn)module_exit(exitfn) 宏来创建这些函数,但它们可以显式定义。)