内核做小是为了热更新、几乎不用重启。评估发现:现在每次发布都重启,主要原因不是内核的大小,而是模块接口的指纹覆盖了整个接口 crate(连注释),以及版本号编进了内核。下面是现状、原因和建议;集中瘦身放在 M7a 之后。
目的:内核做小是为了热更新、几乎不用重启(用户,2026-10-26)。所以衡量标准是 多久必须换一次内核,字节数其次。这份评估不改代码,列出现状、原因和建议; 集中瘦身放在 M7a 之后(用户已同意的顺序),之前的里程碑只顺路做。
内核槽里的文件 340 KiB(LZ4 压缩、4 KiB 对齐):
| 部分 | 未压缩 | 压缩后 |
|---|---|---|
| 内核本体(代码 196 KiB + 只读数据 34 KiB) | 230 KiB | 142 KiB |
| 引导模块(引导用协议栈、virtio、存储、模块管理、救援、DHCP、更新服务) | 300 KiB | 181 KiB |
| PE 引导代码、引导模块目录、对齐 | — | 约 17 KiB |
内核本体按部分(代码和只读数据,字节;改动次数是 2026-10-22 以来碰过该文件的提交数):
| 部分 | 大小 | 改动 | 是什么 | 结论 |
|---|---|---|---|---|
proc、proc/host.rs、proc/image.rs | 34.8 K | 22 | 进程表、clone/线程、信号投递、共享映射与页缓存、exec 和 ELF 加载、定时器、/proc 的数据 | 机制留下;ELF 加载、clone 标志的语义、/proc 数据整理可以移到 linux 模块(内核只映射段、建线程) |
kmain(main.rs) | 31.9 K | 40 | 主循环,很多东西被内联进来 | 改得最勤:先拆开看清楚内联了什么,再把非循环的部分移走 |
sys | 24.0 K | 30 | 给应用的接口(Sys/Net/Kv/Admin 的实现):文件列表、模块列表、spawn、分区增减 | 第二勤:Admin、Kv 的文件辅助大多是策略,可以放到一个"管理"模块,内核只给最小的原语 |
modules | 14.7 K | 15 | 模块安装、启动顺序、状态(modules::apply 一个函数 12 K) | 策略部分移到 modman(已经在引导模块里),内核只留加载和替换 |
uefi + UEFI 入口 + bootstate | 19.8 K | 1 | 启动项、BootNext、引导状态(只在开机、退出固件服务前跑一次) | 适合移到 efiboot 加载器;uefi.rs 是用户写的,由用户决定 |
vm | 10.0 K | 6 | 地址空间、缺页、写时复制 | 机制,留下 |
services、datapath、loader | 14.1 K | 11 | 服务替换、最底层收发包、模块加载 | 机制,留下 |
perf、font、console、acpi | 6.9 K | 10 | 性能统计、控制台输出、ACPI | 输出留下;性能报告的格式化可以移出 |
| 库代码(core、alloc、util) | 约 35 K | — | 格式化、集合 | 随调用者移走而变小 |
另外 bss 388 KiB(64 KiB 启动堆、陷阱栈、控制台缓冲区)不在文件里。
到目前为止每个版本都换了内核、重启了一次。原因按影响排序:
api crate 源码的哈希(crates/api/build.rs,连注释 一起),模块和内核指纹不同就不加载。所以任何接口改动,包括只在两个模块之间用的 接口(比如 linux 模块和 vfs 模块之间的 Vfs),甚至改一行注释,都要换内核。 M2、M3、M4 都改了接口,这一条单独就足以让每次发布都重启。rustros_api::BUILD):内核代码没变,文件也变了,部署流程 就照样上传内核、重启。字节数影响的只是第 3 条的一部分;前两条和内核大小无关,却是现在重启的主要原因。
入口、模块加载与替换、最底层收发包)的才进内核。
Vfs 只要求用 Vfs 的一方匹配。内核本身也调用这些服务(它是中枢),所以这一条单独 还不能让接口变化免重启,但能看清每次到底是哪个接口逼着换内核。sys 的管理接口、modules::apply 的策略、proc 里的 ELF 加载和 /proc 数据、kmain 里内联进来的非循环部分、性能报告。uefi.rs 移到 efiboot(用户决定)。