You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

可加载内核模块__init与__exit宏使用困惑及缓存失效疑问

关于可加载内核模块中__init和__exit宏的疑问

我清楚__init和__exit宏在内置内核模块中的作用,但在定义可加载模块的入口和出口函数时使用这些宏,我完全摸不着头绪,感觉这么做毫无意义。

我做了一个简单实验,编写了如下基础模块:

#include <linux/module.h>
#include <linux/init.h>

static int __init helloworld_init(void) {
    printk("\"Hello world initialization!\"\n");
    return 0;
}

static int init_wrapper(void) {
   // 在这里调用初始化函数
   return helloworld_init();
}

static void __exit helloworld_exit(void) {
    printk("\"Hello world exit, let's try calling init here\"\n");
    init_wrapper();
}

module_init(helloworld_init);
module_exit(helloworld_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("AjB");
MODULE_DESCRIPTION("LKM skeleton");

在/proc/kallsyms中搜索'helloworld',找不到__init函数的符号:

0000000000000000 r _note_7      [helloworld]
0000000000000000 t helloworld_exit      [helloworld]
0000000000000000 d __this_module        [helloworld]
0000000000000000 t cleanup_module       [helloworld]

显然该函数已被移除,所以没出现在结果里。但我在__exit函数中调用了这个__init函数,卸载模块时的内核消息显示调用成功:

Mar 19 17:27:28 aijazVM kernel: [22750.453020] "Hello world exit, let's try calling init here"
Mar 19 17:27:28 aijazVM kernel: [22750.453023] "Hello world initialization!"

这太奇怪了:__init函数的符号不存在,但同一文件内的函数居然还能调用它。我猜测可能是相关内存缓存行未失效,且同一编译单元内的函数引用是基于偏移的。但我尝试刷新缓存后,内核依然没有崩溃:

Mar 19 18:01:33 aijazVM kernel: [24795.884795] "Hello world initialization!"
Mar 19 18:02:01 aijazVM kernel: [24823.169160] echo (15514): drop_caches: 3
Mar 19 18:02:12 aijazVM kernel: [24834.528229] "Hello world exit, let's try calling init here"
Mar 19 18:02:12 aijazVM kernel: [24834.528232] "Hello world initialization!"

我有两个疑问:

  • 为什么__init函数的符号不在kallsyms中,但同一编译单元内的__exit函数仍能成功调用它?
  • 有没有方法强制CPU失效整个缓存层级?有没有架构无关的安全方式,让处理器失效本地缓存(L1/L2/L3)?

内容的提问来源于stack exchange,提问作者Skegg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 21:22:54