Kairo 是一个以 Rust 为主实现的操作系统原型,目标是在保证内核核心模块可控、可维护、尽量内存安全的前提下,逐步提供对 Linux 用户态程序的兼容运行能力。
当前仓库处于早期阶段,现有代码主要聚焦于内核启动、基础输出和构建流程。本文档用于定义项目目标、系统架构、兼容策略和演进路线,作为后续开发的统一技术基线。
Kairo 的核心目标不是“重新实现一个完整 Linux 发行版”,而是构建一个基于 Rust 的新操作系统,并优先实现 Linux 用户态 ABI 兼容。
项目分为三个层次目标:
- 能够稳定启动到用户态,并运行最小用户程序。
- 能够运行一部分常见 Linux ELF 程序,优先支持简单命令行工具。
- 在兼容能力逐步增强的同时,保持内核模块化和 Rust 主导实现。
为了避免目标过大,Kairo 早期不追求完整硬件生态兼容,也不追求一次性支持所有 Linux 应用。项目优先保证可验证的里程碑推进。
内核中的大部分逻辑使用 Rust 实现,仅在以下场景保留少量汇编:
- 启动入口
- 中断和异常入口
- 上下文切换
- 特定架构寄存器操作
如果某个接口设计在理论上更优雅,但会显著增加 Linux 程序兼容成本,则优先考虑兼容行为。对于目标中的用户态兼容而言,ABI 和行为一致性比内部抽象更重要。
项目采用分阶段演进策略,优先实现“能跑起来”的最小闭环,再逐步扩展系统调用、文件系统、线程、网络和动态链接能力。
早期仅优先支持 QEMU 和 virtio 设备,以降低驱动开发复杂度,加快调试与验证速度。
Kairo 建议采用“Rust 混合内核 + Linux ABI 兼容层”的总体路线。
这意味着:
- 内核本身不是 Linux 内核。
- 用户态执行环境尽量提供 Linux 程序期望的接口。
- 文件系统布局、进程模型、系统调用接口、伪文件系统等尽量向 Linux 靠拢。
从工程角度看,这条路线比“完全重写 Linux”更可行,也比“做一个纯教学型内核”更有实际价值。
+------------------------------------------------------+
| Linux 应用程序 (busybox, shell, tools, services) |
+------------------------+-----------------------------+
|
v
+------------------------------------------------------+
| Linux ABI 兼容层 |
| - syscall dispatcher |
| - ELF 加载与解释器支持 |
| - 信号、线程、futex 语义 |
| - /proc、/dev、/tmp 等接口映射 |
+------------------------+-----------------------------+
|
v
+------------------------------------------------------+
| 用户态基础服务 |
| - init |
| - 动态链接支持 |
| - 设备管理与系统服务 |
+------------------------+-----------------------------+
|
v
+------------------------------------------------------+
| Rust 内核 |
| - 启动与架构支持 |
| - 内存管理 |
| - 调度器 |
| - VFS |
| - IPC |
| - 网络栈 |
| - 驱动框架 |
+------------------------------------------------------+
|
v
+------------------------------------------------------+
| x86_64 / aarch64 硬件 |
+------------------------------------------------------+
Kairo 适合采用偏宏内核的混合设计,而不是纯微内核。
原因很直接:Linux 用户态兼容要求高频 syscall、复杂进程语义和文件系统行为,如果过早把所有功能拆成用户态服务,会显著增加早期复杂度和调试成本。
建议内核包含以下核心子系统。
职责包括:
- UEFI 启动支持
- 内核镜像加载
- 页表初始化
- 内存映射准备
- 中断描述符表和异常入口初始化
- 启动日志输出
早期建议优先支持 x86_64,待核心抽象稳定后再扩展 aarch64。
内存管理模块负责:
- 物理页分配器
- 虚拟地址空间管理
- 用户态与内核态地址空间隔离
- 页错误处理
mmap、munmap、mprotectbrk堆扩展
这是 Linux 程序兼容的核心基础之一,因为动态链接器、C 运行时和线程库都会依赖这些行为。
调度子系统负责:
- 进程创建与销毁
- 线程创建与切换
- 抢占式调度
- 多核调度基础
- 线程组与任务状态管理
- 阻塞与唤醒
如果要兼容 Linux 线程模型,后续必须提供接近 Linux 的 clone 语义和 futex 行为。
VFS 应作为内核中的关键抽象层,统一管理:
- inode
- dentry
- file
- mount
- 路径解析
- 权限校验
早期可以先实现最小 VFS,再挂载 tmpfs、只读根文件系统和 procfs/devfs。
建议按以下顺序推进:
tmpfs- initramfs
- 只读
ext4 - 可写
ext4或自研日志文件系统
早期目标是支撑系统启动和基础命令运行,因此先保证可靠读取和最小写能力,而不是追求复杂特性。
驱动层早期建议聚焦 virtio:
virtio-blkvirtio-netvirtio-gpuvirtio-input- 串口输出
- 基础定时器
这样可以在 QEMU 中快速形成完整调试闭环。
为了兼容 Linux 程序,内核至少需要支持:
- pipe
- unix socket
- signal
- 共享内存
- futex
其中 futex 将直接影响 pthread、glibc 和大量多线程程序是否可运行。
网络建议在基础兼容稳定后引入,分阶段实现:
- loopback
- 基础 IPv4
- TCP/UDP
- socket API
poll/select/epoll
“能兼容 Linux 程序”并不只是实现一组 syscall 编号,而是要兼容一整套用户态预期。
内核或配套加载器需要支持:
ELF64- 静态链接程序
- PIE 可执行文件
- 共享库映射
PT_INTERP- 用户栈初始化
auxv
如果没有正确的 ELF 装载语义,很多程序甚至无法进入 main。
早期应优先支持最常见的一批系统调用:
readwriteopenatclosemmapmunmapmprotectbrkexecveexitwait4clonefutexrt_sigactionrt_sigprocmaskclock_gettimenanosleepstatfstatnewfstatatgetdents64ioctlpipe2dupdup3
在 x86_64 平台上,还需要较早支持 arch_prctl,否则线程本地存储和运行时初始化会卡住。
Linux 程序通常依赖如下语义:
fork + execclone创建线程- 线程组
- PID 与 TID 区分
- 父子进程回收
- 会话与进程组
因此 Kairo 的任务模型不能只停留在“轻量线程切换”层面,必须从一开始就给进程和线程留下清晰抽象边界。
信号是 Linux 兼容中最容易被低估的部分之一。建议至少支持:
SIGINTSIGTERMSIGCHLDSIGSEGVSIGKILLSIGSTOP
需要实现的语义包括:
- 信号处理器注册
- 信号屏蔽字
- 挂起信号队列
- 返回用户态时的信号投递
- 信号帧构造与恢复
许多 Linux 程序不仅依赖 syscall,也会访问约定路径。系统应逐步实现:
/proc/self/proc/self/maps/proc/meminfo/proc/cpuinfo/dev/null/dev/zero/dev/random/dev/urandom/dev/tty/tmp
这些接口对 shell、运行时、调试器和基础工具都非常重要。
这是项目成败的关键之一。
建议采用以下路线:
这是最现实的起点,因为:
- 依赖更少
- 不需要先完整实现动态链接器
- 行为更容易调试
目标程序可以优先选择:
busybox静态版- 自定义 hello world
- 简单工具程序
在此阶段需要补齐:
- 共享库映射
- 动态链接初始化
- TLS 基础
- 更完整的内存映射行为
glibc 兼容难度明显更高,主要痛点包括:
- 线程本地存储
- 更严格的
futex语义 - 信号细节
/proc依赖vDSOpthread行为细节
因此项目必须明确:glibc 是中后期目标,不应在系统尚未稳定时强行推进。
第一个用户态进程负责:
- 挂载伪文件系统
- 初始化基础设备节点
- 启动 shell 或服务管理器
- 管理系统关闭与故障恢复
早期不必做完整 service manager,一个简化版 init 即可。
建议包含:
- ELF 加载支持组件
- 动态链接兼容组件
- 基础 shell
- 调试与日志工具
建议从一开始就接近 Linux 目录结构:
/
├── bin
├── sbin
├── lib
├── lib64
├── usr
│ ├── bin
│ ├── lib
│ └── share
├── etc
├── proc
├── dev
├── tmp
├── var
└── home
这样更方便移植已有用户态工具,也能减少后续目录兼容的额外成本。
Rust 可以显著降低内存安全漏洞,但不能替代系统级安全设计。Kairo 需要在架构层面落实以下原则:
- 用户态和内核态严格隔离
- syscall 参数必须完整校验
- 驱动访问边界清晰
- 权限与身份模型明确
- 核心对象使用能力边界或访问控制机制
中后期可以逐步扩展:
- capability 机制
- seccomp 风格过滤
- 可执行文件签名
- 审计日志
目标:
- UEFI 启动
- 页表初始化
- 异常和中断框架
- 串口日志
- 基础内存分配
- 进入第一个用户态程序
验收标准:
- 能在 QEMU 中稳定启动
- 能输出启动日志
- 能运行最小静态程序
目标:
- 进程和线程基础抽象
execve- 基础 VFS
tmpfs/dev/null和/dev/zeroread/write/openat/close
验收标准:
- 可运行静态版 BusyBox
- 可执行简单文件读写操作
目标:
mmap/brkstat/getdents64clonefutex- 信号机制基础
/proc最小实现
验收标准:
- 可运行 shell
ls、cat、echo等命令可正常工作
目标:
- TCP/IP 栈
- socket API
poll/select/epollioctl的常见路径支持
验收标准:
- 可运行简单客户端程序
- 可启动基础网络服务
目标:
- 更完整 TLS
- 更准确 futex 语义
vDSO- 更完整
/proc glibc适配修正
验收标准:
- 可运行更多复杂 Linux 用户态程序
结合当前仓库中已有的 kairo-kernel 和 xtask,推荐逐步演进为如下结构:
Kairo/
├── README.md
├── kairo-kernel/
│ ├── src/
│ │ ├── arch/
│ │ ├── boot/
│ │ ├── mm/
│ │ ├── sched/
│ │ ├── syscall/
│ │ ├── fs/
│ │ ├── driver/
│ │ └── user/
│ ├── Cargo.toml
│ └── x86_64-kairo.json
├── userland/
│ ├── init/
│ ├── loader/
│ └── ports/
├── docs/
│ ├── architecture.md
│ ├── abi-compat.md
│ └── roadmap.md
└── xtask/
早期不必一次性建立全部目录,但建议尽早按模块边界拆分,避免后续在单文件或单模块中堆积过多职责。
现有 kairo-kernel/src/main.rs、kairo-kernel/src/serial.rs 和 kairo-kernel/src/vga_buffer.rs 更接近“最小内核启动原型”阶段。
这很好,因为它对应了本设计中的 Phase 1。后续工作建议按以下顺序展开:
- 把启动、输出、配置相关逻辑从当前入口中拆成更清晰的模块。
- 引入基础内存管理抽象,为用户态装载做准备。
- 建立任务模型和 syscall 框架。
- 再推进 ELF 加载和最小用户程序执行。
项目最难的部分不在“把内核跑起来”,而在 Linux 兼容行为的细节一致性。需要特别警惕以下风险:
- 低估
glibc兼容成本 - 低估
clone + futex + signal的耦合复杂度 - 低估
/proc和ioctl的生态依赖 - 过早引入过多硬件支持导致调试面过大
因此项目管理上应坚持一个原则:
先在 QEMU + virtio + musl 静态程序闭环下做稳定,再逐步扩大兼容面。
Kairo 的推荐路线可以概括为:
Rust 混合内核、优先支持虚拟化平台、以 Linux 用户态 ABI 兼容为主线、先支持 musl 静态程序,再逐步迈向动态链接和更强兼容能力。
这条路线兼顾了工程可行性、技术挑战性和长期演进空间,适合作为一个严肃的 Rust 操作系统项目基础。
在本文档基础上,后续建议优先补充三类文档:
- 架构分层文档,明确内核模块边界与接口。
- Linux ABI 兼容清单,跟踪 syscall 和行为支持状态。
- 启动与运行指南,统一 QEMU 调试流程。
如果继续推进,我下一步可以直接补:
- 一份更细的
docs/architecture.md,把内核模块接口详细展开。 - 一份
docs/roadmap.md,按里程碑拆成具体开发任务。 - 一份面向当前代码的重构方案,把
kairo-kernel先整理成更适合扩展的骨架。