LumenOS(源自拉丁语 lumen,意为"光")是一个参考 phil-opp/blog_os 和 OpRustLearning 设计的 x86_64 学习型微内核操作系统,使用 Zig 语言 编写,通过 Limine 引导协议支持 BIOS (MBR) 和 UEFI (GPT) 双启动模式。
本项目的目标是帮助学习者理解操作系统的核心概念,包括:裸机编程、帧缓冲区显示、中断处理、内存分页、堆分配等。代码包含大量中文注释,降低学习门槛。
- Zig 语言实现 — 使用 Zig 的 comptime 特性和零开销抽象编写底层系统代码
- Limine 引导协议 — 通过 Limine 引导程序同时支持 BIOS 和 UEFI 启动
- 帧缓冲区渲染 — 使用嵌入式 8x16 VGA 位图字体在像素帧缓冲区上渲染文字
- 丰富的中文注释 — 每个模块都包含详细的原理说明和设计思路
- 模块化架构 — 清晰分离显示、串口、GDT、中断、内存管理等子系统
- 完整的启动链路 — 从固件引导到堆分配,覆盖操作系统启动的完整流程
- 交互式键盘回显 — 启动后可直接在屏幕上看到键盘输入
| 特性 | Rust 版本 | Zig 版本 |
|---|---|---|
| 引导协议 | bootloader crate v0.11 | Limine 引导协议 |
| 构建系统 | Cargo + Makefile | Zig Build System + Makefile |
| 字体渲染 | noto-sans-mono-bitmap (抗锯齿) | 嵌入式 8x16 VGA 位图字体 |
| 串口驱动 | uart_16550 crate | 直接端口 I/O |
| GDT/IDT | x86_64 crate 抽象 | 手动构造数据结构 + 内联汇编 |
| PIC 驱动 | pic8259 crate | 直接端口 I/O |
| 键盘解码 | pc-keyboard crate | 手写扫描码解码器 |
| 堆分配器 | linked_list_allocator crate | 手写空闲链表分配器 |
| 页表操作 | x86_64 crate 的 Mapper trait | 手动四级页表遍历 |
| 模块 | 文件 | 功能描述 |
|---|---|---|
| 底层硬件 | src/x86.zig |
端口 I/O、CPU 指令(HLT/CLI/STI 等)封装 |
| 帧缓冲区 | src/framebuffer.zig |
像素帧缓冲区文本渲染,滚屏,格式化输出 |
| 字体数据 | src/font.zig |
嵌入式 8x16 VGA 位图字体 (ASCII 32-126) |
| 串口输出 | src/serial.zig |
UART 16550 驱动,调试与测试输出 |
| GDT/TSS | src/gdt.zig |
全局描述符表 + 任务状态段 + 中断栈表 |
| 中断处理 | src/idt.zig |
IDT + 断点/双重错误/页错误处理 + 定时器/键盘中断 |
| PIC 驱动 | src/pic.zig |
8259 可编程中断控制器初始化与 EOI |
| 键盘驱动 | src/keyboard.zig |
PS/2 扫描码集 1 解码器 (US QWERTY) |
| 内存管理 | src/memory.zig |
四级页表操作 + 物理帧线性分配器 |
| 堆分配 | src/allocator.zig |
堆初始化 + 空闲链表分配器 |
| 内核入口 | src/main.zig |
内核入口点,初始化序列,Limine 协议请求 |
- Zig >= 0.14.0 — 编译内核
- QEMU (
qemu-system-x86_64) — 运行内核镜像 - GNU Make — 构建自动化
- xorriso — 创建 ISO 镜像(可选)
- sgdisk + mtools — 创建 HDD 镜像(可选)
# 确认 Zig 版本
zig version
# 确认 QEMU 已安装
qemu-system-x86_64 --version
# 安装构建工具(Ubuntu/Debian)
sudo apt install xorriso mtools gdisk# 编译内核
make kernel
# ── ISO 镜像模式 ──
# 创建 ISO 镜像(首次运行会自动克隆 Limine)
make all
# 以 BIOS 模式运行
make run-bios
# 以 UEFI 模式运行(自动下载 OVMF)
make run
# ── HDD 镜像模式 ──
make all-hdd
make run-hdd-bios # BIOS 模式
make run-hdd # UEFI 模式
# ── 其他 ──
make clean # 清理构建产物
make distclean # 清理所有(包括 Limine 和 OVMF)
make help # 查看所有可用命令LumenOS-Zig/
├── build.zig # Zig 构建配置(目标平台、链接脚本)
├── build.zig.zon # Zig 包管理配置(limine-zig 依赖)
├── linker.ld # 内核链接脚本(高半地址空间)
├── limine.conf # Limine 引导配置
├── src/
│ ├── main.zig # 内核入口点(_start)
│ ├── x86.zig # x86_64 底层硬件操作
│ ├── serial.zig # UART 16550 串口驱动
│ ├── framebuffer.zig # 帧缓冲区文本渲染驱动
│ ├── font.zig # 嵌入式 8x16 VGA 位图字体
│ ├── gdt.zig # 全局描述符表 + 任务状态段
│ ├── idt.zig # 中断描述符表 + 异常/硬件中断处理
│ ├── pic.zig # 8259 可编程中断控制器驱动
│ ├── keyboard.zig # PS/2 键盘扫描码解码器
│ ├── memory.zig # 页表操作 + 物理帧分配器
│ └── allocator.zig # 堆内存初始化 + 空闲链表分配器
├── Makefile # 构建命令(ISO/HDD 镜像 + QEMU 运行)
├── LICENSE # Apache-2.0 许可
└── README.md
固件启动(BIOS POST 或 UEFI 初始化)
│
▼
Limine 引导加载程序
│ ● 解析 limine.conf 配置
│ ● 加载内核 ELF 文件
│ ● 检测物理内存布局
│ ● 建立 HHDM(全部物理内存的高半直接映射)
│ ● 初始化帧缓冲区
│ ● 设置四级页表
│ ● 切换到 64 位长模式
▼
_start() ← 我们的代码从这里开始
_start()
│
├── serial.init() 初始化 UART 串口
│
├── framebuffer.init() 初始化帧缓冲区文本渲染
│
├── printBanner() 打印 ASCII 艺术横幅
│
├── gdt.init() 加载 GDT + TSS + 重载段寄存器
│
├── idt.init() 加载 IDT(异常 + 硬件中断)
│
├── pic.init() 初始化 8259 PIC(重映射 IRQ)
├── x86.sti() 执行 STI,CPU 开始响应中断
│
├── memory.init() 初始化物理帧分配器
│
├── heap.initHeap() 映射堆页 + 初始化空闲链表
│
├── demoHeapAllocation() 演示 i32 和数组的堆分配
│
└── x86.hltLoop() HLT 低功耗主循环
├── 定时器中断 → 静默处理
└── 键盘中断 → 解码扫描码 → 回显字符到帧缓冲区
建议按以下顺序阅读源码,每个文件都有详细的中文注释:
src/main.zig— 了解整体启动流程和 Limine 协议src/x86.zig— 了解 x86_64 底层硬件操作(端口 I/O、CPU 指令)src/serial.zig— 了解串口通信和 Zig 的 Writer 接口src/framebuffer.zig+src/font.zig— 理解帧缓冲区像素渲染src/gdt.zig— 理解 GDT、TSS 和段寄存器src/idt.zig— 理解 IDT、中断桩函数和异常处理src/pic.zig— 理解 8259 PIC 中断控制器src/keyboard.zig— 理解 PS/2 键盘扫描码解码src/memory.zig— 理解 x86_64 四级页表和帧分配src/allocator.zig— 理解堆内存的实现原理
- Writing an OS in Rust — Philipp Oppermann 的原创教程
- 使用 Rust 编写操作系统 — 中文翻译
- OpRustLearning — 本项目的 Rust 原版
- Limine Boot Protocol — Limine 引导协议规范
- limine-zig — Limine 的 Zig 绑定
- OSDev Wiki — 操作系统开发百科全书
Apache-2.0