第98期 | insmod 一敲,模块和内核签了什么契约?

操作系统 · · 九羲科技

1995 年,Linux 1.2 干了一件大胆的事:允许一段"外来代码",在系统不重启的情况下住进内核。从此,"加驱动"不再等于"重编内核"。

一、insmod 不是安装,是签约

1995 年 3 月,Linux 1.2 带来可加载内核模块¹。在此之前,加功能唯一的办法是重编整个内核、再重启。LKM 把内核从"铁板一块"变成了"活字印刷"——毕昇的泥活字,一字一模,按需拣字,印完拆回字盘;1995 年的 Linux,选了活字。

insmod 听着像"安装",干的却是"链接"的活。.ko 文件就是一段还没安家的 ELF,跳转地址全是空位。insmod 把它读进内存后,苦活在内核里:重定位——替它算好每一处跳转的真实地址;符号解析——模块要调的 printk、kmalloc,得去内核导出的符号表(EXPORT_SYMBOL)里对上暗号¹。对上了,内核才调 module_init——签字画押,进驻 /sys。

2002 年,Rusty Russell 在 2.5 开发版里把这套加载器重写了一遍²,工具从 modutils 换成 module-init-tools(后来的 kmod)。LKML 上吵了几个月,争的是卸载时的引用计数 try_module_get:谁还在用?没人用了才能拆。请神容易送神难,进来要签约,出去得先结清账。

反常识的是:模块和内核之间,没有"隔离",只有"信任"。进了内核的模块,与内核同地址空间、同最高权限——不是客人,是入赘。内核对驱动接口还不做稳定承诺(第 90 期讲过),所以模块的自由从来不是"想怎么待就怎么待",而是"想进来,就得跟上内核的步伐"。

二、AI 时代的模块,像一次面试

2026 年 10 月,Linux 7.4 合并窗口,Rust for Linux 拉取请求约 17,000 行——别被数字骗了:大头是内置 Zerocopy 库一次升 8 个版本,外加 mem、ratelimit 两个新模块和工具链调整³。新功能不多,搭的都是架子:先把路修好,车自然会来——好一个"发展性研究"的现场。

同周期的另一条线更贴题:NVIDIA 的 Rust 显卡驱动 Nova 继续推进,10 月 5 日在布拉格 Linux Plumbers 大会上被公开描述为 Open RM 的长期替代品⁴——Open RM 正是 NVIDIA 在树外发布的闭源内核模块。模块的本质是信任边界:内核允许外来代码以最高权限运行。Rust 改写的是这份契约的担保方式:从"C 写、人保证"变成"Rust 写、编译器保证"。

Ken Thompson 1984 年在图灵奖演讲《Reflections on Trusting Trust》里点破:信任链的尽头是编译器⁵。所以模块机制的下一章,写的不是"怎么装",而是"凭什么信"。Linux 早有雏形:module_param——模块参数就是最早的"声明式配置",insmod 时传个 debug=1,或写进 /sys/module/<名字>/parameters/。6.19 周期补上的 Rust 模块参数原生支持⁶,让 Rust 模块的参数声明出现在同样的位置。可以说:模块参数,是写给内核的提示词——第 59 章"提示词即配置",1995 年就埋了伏笔。

三、今晚,数一数你电脑里的模块

找一台手边的 Linux 机器,三条命令看现场:

lsmod | head——最后一列"Used by"就是 try_module_get 在数数:2002 年 Rusty 在 LKML 上吵赢的引用计数,此刻正在你眼前工作。

modinfo -p xfs——看一个文件系统模块声明了多少"可调参数"。每个参数,都是当年作者留给运维的"提示词位"。

ls /lib/modules/$(uname -r)/kernel/drivers | wc -l——数一数躺在硬盘里、还没装进内核的模块。几千个 .ko 安静地等着被叫醒:你的内核不是一成不变的东西,它是个随时能变形的系统——这是"不住于相"最工程化的版本。

给生产机加新网卡,不用重启:modprobe 装进去,dmesg 看 module_init 有没有报错。模块机制三十年没变的核心承诺就一句:世界变了,系统不用推倒重来,换一块活字就行。

insmod 的四步:读入 .ko → 内核做重定位 → 符号表对暗号 → module_init 签字进驻。

觉 然 小 注

"如来说世界,即非世界,是名世界。"模块也是假名安立:.ko 文件里并没有"模块"这个实体,只有一段待安家的代码,和一份"进来之后守什么规矩"的契约。insmod 落下的那一刻,它和内核已经不分彼此。凡发生必有利于我:系统敢让外来者进来,是因为它相信契约;你敢不敢让新东西进来,取决于你信不信自己定的规矩。

引 用 与 出 处

  1. [1] M. Tim Jones. Anatomy of Linux loadable kernel modules. IBM developerWorks, 2008. https://mirrors.pdp-11.net/_vax/www.bandwidthco.com/whitepapers/os/linux/Anatomy%20of%20Linux%20Loadable%20Kernel%20Modules.pdf
  2. [2] Rusty Russell. [PATCH] In-kernel module loader 1/7. LKML, 2002-10-18. https://www.cs.helsinki.fi/linux/linux-kernel/2002-41/1912.html
  3. [3] pbxscience. Linux 7.4 Brings About 17,000 Lines of Rust Code, but the Real Story Is the Infrastructure. 2026-10-24. https://pbxscience.com/linux-7-4-brings-about-17000-lines-of-rust-code-but-the-real-story-is-the-infrastructure/ (二手转引)
  4. [4] WebProNews. NVIDIA's Nova Driver Gains Ground in Linux 7.4 as Path to Official Open Kernel Support Emerges. 2026-10(引 Phoronix 对 2026-10-05 布拉格 Linux Plumbers 大会报道). https://www.webpronews.com/nvidias-nova-driver-gains-ground-in-linux-7-4-as-path-to-official-open-kernel-support-emerges/ (二手转引)
  5. [5] Ken Thompson. Reflections on Trusting Trust. Communications of the ACM, 27(8), 1984. https://doi.org/10.1145/358198.358210
  6. [6] Portal Linux. Rust in the Linux Kernel Reaches Critical Milestone: Native Module Parameters Arrive in v6.19. 2025-12. http://portallinuxferramentas.blogspot.com/2025/12/rust-in-linux-kernel-reaches-critical.html (二手转引)

· · ·

← 返回资讯中心