RustROS · 2026-10-29 · 地址空间

内核搬到高半区:固定地址的程序能跑了

进程拿到整个低半区,Go 默认编译的程序和 Debian 的 python3 在 RustROS 容器里照常运行。内核同时加上了常规的内存保护。按用户确认的设计(docs/user-address-space-design.md)完成,四项决定都按建议。

内核改动有,需重启一次PE 文件 401,408 → 405,504 字节(+4 KiB)
接口改动有Hw 的设备地址和 DMA 调用;所有模块重装
回归测试通过260 个单元测试;KVM 测试见下
转发18.9 Gbit/s · 366 kppsTCP 单流 / 64 字节单流,和之前持平

问题为什么以前跑不了

以前内核用"虚拟地址 = 物理地址"的映射占着低 64 TiB,进程只能从 64 TiB 起放东西。按固定地址链接的程序(Go 默认编译、Debian 的 python3)要装在 0x400000,正好落在内核那块里,所以装不进去。python3 自己的安装脚本也要调用 python3,所以 apt-get install python3 本身就失败。

布局现在的地址空间

范围用途
0x10000 – 0x7FFF_FFFF_F000进程自己的(低半区整个)
0xFFFF_8000_0000_0000线性映射:全部内存,不可执行
0xFFFF_C000_0000_0000设备寄存器,按需映射,不缓存
0xFFFF_D000_0000_0000模块,按页映射:代码只读、数据不可执行
0xFFFF_FFFF_8000_0000内核本身:代码只读,其余不可执行

所有常量都在 crates/api/src/layout.rs 一处。系统调用的开销和以前一样:内核的高半区在每个地址空间里都有,不切页表。

一起做的为以后少留后患

验收面板要的几项

检查Debian 13(debian_test)LXC Debian 13 cloud,路由容器(node_test)
Go 默认编译,静态(8 个 goroutine、定时器、64 MiB、GC)通过通过
Go 默认编译,cgo(glibc 的 ld.so)通过通过
apt-get install -y python3通过通过
python3 -c 'import ssl, json, sqlite3'通过通过
pip --version(python3-pip,不装推荐包)pip 25.1.1通过

新的 lowaddr 测试程序(proc_test)是真正装在 0x400000 的固定地址程序,13 项检查全部通过:MAP_FIXED 映射 0x10000 和 0xc000000000、地址提示按原样给、0x10000 以下映射不了;读原恒等映射的地址、内核本身、线性映射、vsyscall 页都会被 SIGSEGV 终止;两次运行的栈和 mmap 地址不同。

顺带修好测试里发现的问题

测试结果

还有的已知问题(不是这次引入的):私有文件映射是整个复制进内存的。apt 会映射约 80 MB 的包缓存,所以在只有 256 MiB 内存的测试机里 fork 会失败("Failed to fork")。Debian 测试机现在给 1 GiB,客户容器的内存比这大得多。以后可以改成从页缓存按需读入。

发布影响