kallsyms 中不存在 init 函数

init function not present in kallsyms

我写了一个简单的hello world内核模块

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/delay.h>

MODULE_LICENSE("GPL");
static int __init test_hello_init(void)
{
    printk(KERN_INFO"%s: In init\n", __func__);
    return 0;
}

static void __exit test_hello_exit(void)
{
    printk(KERN_INFO"%s: In exit\n", __func__);
}

module_init(test_hello_init);
module_exit(test_hello_exit);

加载模块后,我正在检查添加到 /proc/kallsysms 中的所有符号。我没有观察到 test_hello_init。为什么我们没有

0000000000000000 r __func__.20413   [hello]
0000000000000000 t test_hello_exit  [hello]
0000000000000000 r __func__.20417   [hello]
0000000000000000 r _note_6  [hello]
0000000000000000 d __this_module    [hello]
0000000000000000 t cleanup_module   [hello]

使用 Linux 内核 5.8 源作为参考,“kallsyms”的模块符号 table 是通过调用 add_kallsyms()(在“kernel/module .c") 在模块加载时(调用路径:系统调用 init_module()load_module()post_relocation()add_kallsyms()),在模块完全初始化之前。它添加了模块的完整符号table(由模块的kallsyms成员指向),还构造了一个cut-down,核心符号table(在模块的core_kallsyms member) 在模块初始化后使用。

从完整符号table到核心符号table的切换发生在调用

    /* Switch to core kallsyms now init is done: kallsyms may be walking! */
    rcu_assign_pointer(mod->kallsyms, &mod->core_kallsyms);

来自 do_init_module()(调用路径:系统调用 init_module()load_module()do_init_module())。这发生在模块的 init 函数(如果有)被调用之后。

do_init_module() 还负责在模块初始化成功后丢弃模块的初始内存部分(包含标记为 __init 的函数和标记为 __initdata 的数据)。这是通过将指向模块初始化部分的指针添加到静态 init_free_list 列表并安排工作项以释放列表中的任何部分来完成的:

    freeinit = kmalloc(sizeof(*freeinit), GFP_KERNEL);
    freeinit->module_init = mod->init_layout.base;
    if (llist_add(&freeinit->node, &init_free_list))
        schedule_work(&init_free_wq);

计划的工作功能是do_free_init()。用空列表交换 init_free_list 并遍历 init_free_list 的原始副本以释放模块的初始内存部分:

    list = llist_del_all(&init_free_list);
    llist_for_each_safe(pos, n, list) {
        initfree = container_of(pos, struct mod_initfree, node);
        module_memfree(initfree->module_init);
        kfree(initfree);
    }