跳转到内容

架构概览

OpenOS 采用微内核架构,这是现代操作系统设计的一种方法。与宏内核(如 Linux)不同,微内核仅在内核空间运行最核心的服务,而将驱动和大部分系统服务放在用户空间运行。

最小化内核

内核仅包含最核心的服务:内存管理、任务调度、IPC 通信。其他功能(驱动、文件系统、网络)运行在用户空间。

故障隔离

用户空间的驱动崩溃不会导致内核崩溃。每个服务运行在独立的地址空间中,相互隔离。

最小可信计算基

内核代码量小,更容易进行形式化验证和安全审计。seL4 微内核已经过形式化验证。

灵活的服务组合

服务可以独立重启、升级和替换。系统可以根据需要动态组合不同的服务。

┌─────────────────────────────────────────────────────────────┐
│ 用户空间 (Ring 3) │
├─────────────────────────────────────────────────────────────┤
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 文件系统 │ │ 网络栈 │ │ 驱动程序 │ │ 显示服务 │ │
│ │ 服务器 │ │ 服务器 │ │ │ │ │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │ │
│ └──────────────┴──────────────┴──────────────┘ │
│ │ IPC │
├──────────────────────────┼──────────────────────────────────┤
│ 内核空间 (Ring 0) │
├─────────────────────────────────────────────────────────────┤
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 内存管理 │ │ 任务调度 │ │ IPC 子系统 │ │ 中断处理 │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
├─────────────────────────────────────────────────────────────┤
│ 硬件 │
└─────────────────────────────────────────────────────────────┘

OpenOS 内核由以下核心模块组成:

负责 CPU 特定的初始化和管理:

模块文件职责
GDTgdt.rs全局描述符表,段选择子,TSS
IDTinterrupts.rs中断描述符表,异常和 IRQ 处理
PICpic8259.rs可编程中断控制器初始化
SYSCALLsyscall.rsSYSCALL/SYSRET MSR 配置

硬件抽象和输出:

驱动文件职责
VGAvga.rs帧缓冲文本渲染,8×16 位图字体
串口serial.rsUART 16550 驱动,调试输出
模块文件职责
堆分配器allocator.rslinked_list_allocator,100 KiB 堆
帧分配器frame_alloc.rs物理帧分配(bump 分配器)
模块文件职责
任务task.rsTaskId(原子),TaskState,任务控制块
调度器scheduler.rs轮询调度器,就绪队列
模块文件职责
Handlehandle.rsHandle 结构体、Rights 位掩码、HandleTable
KernelObjecthandle.rs内核对象枚举(ChannelEndA/B 等)
模块文件职责
Channelmod.rs同步会合消息传递
EndStatemod.rsChannel 端点状态,pending_handles
模块文件职责
分发器mod.rs22 个系统调用分发
编号number.rs系统调用号常量
模块文件职责
ELF 解析elf.rsELF64 解析器,PT_LOAD 段加载
Initrdinitrd.rsInitrd 归档解析器
模块文件职责
VFSmod.rs虚拟文件系统占位符
BIOS → bootloader (0.11) → kernel_main()
├─ 1. VGA 初始化 (drivers/vga.rs)
│ └─ 清屏,初始化帧缓冲
├─ 2. 串口初始化 (drivers/serial.rs)
│ └─ UART 16550 配置
├─ 3. GDT + TSS (arch/x86_64/gdt.rs)
│ └─ 段描述符,双重故障栈
├─ 4. IDT (arch/x86_64/interrupts.rs)
│ └─ 异常 + IRQ 处理函数
├─ 5. PIC 初始化 (pic8259)
│ └─ 重映射 IRQ 0-15 → INT 32-47
├─ 6. 开启中断 (sti 指令)
├─ 7. 堆分配器 (memory/allocator.rs)
│ └─ linked_list_allocator @ 0x4444_4444_0000
├─ 8. Handle 系统 (handle.rs)
│ └─ HandleTable,KernelObject
├─ 9. IPC 子系统 (ipc/mod.rs)
│ └─ Channel 创建,消息传递
├─ 10. 系统调用处理 (syscall/mod.rs)
│ └─ 22 个系统调用分发器
├─ 11. 任务调度器 (task/scheduler.rs)
│ └─ 轮询调度,就绪/阻塞队列
├─ 12. ELF 加载器 (elf.rs)
│ └─ ELF64 解析,initrd 支持
├─ 13. 用户空间服务 (task/user.rs)
│ └─ Ring 3 切换,console_svc.elf
└─ 14. 空闲循环 (hlt 指令)

OpenOS 采用高半内核设计,内核映射在虚拟地址空间的高地址部分:

虚拟地址空间:
0xFFFFFFFFFFFFFFFF ┌────────────────────┐
│ │
│ 内核空间 │ Ring 0
│ (高半) │
0xFFFFFFFF80100000 ├────────────────────┤ ← 内核 .text
│ .text / .rodata │
│ .data / .bss │
│ 堆 (100 KiB) │
0xFFFFFFFF80000000 ├────────────────────┤ ← KERNEL_OFFSET
│ │
│ (未映射间隙) │
│ │
0x00007FFFFFFFFFFF ├────────────────────┤ ← 用户栈顶
│ 用户栈 │ Ring 3
│ (向下增长) │
0x00007FFF00000000 ├────────────────────┤
│ │
│ 用户代码/数据 │
│ │
0x0000000000400000 ├────────────────────┤ ← 用户程序基址
│ (保留/空) │
0x0000000000000000 └────────────────────┘
区域虚拟地址大小权限
VGA 文本缓冲区0xB80004 KiBRW(恒等映射)
内核 .text0xFFFFFFFF80100000~64 KiBRX
内核 .data/.bss0xFFFFFFFF80110000~16 KiBRW
内核堆0x4444_4444_0000100 KiBRW
内核栈 (RSP0)TSS.rsp032 KiBRW
IST[0](双重故障)TSS.ist[0]20 KiBRW
特性微内核 (OpenOS)宏内核 (Linux)
内核大小小 (~100 KiB)大 (~10 MiB)
驱动位置用户空间内核空间
故障隔离强(驱动崩溃不影响内核)弱(驱动崩溃导致内核崩溃)
IPC 开销高(消息传递)低(函数调用)
可验证性高(代码量小)低(代码量大)
性能中等(IPC 开销)高(直接调用)
灵活性高(服务可独立更新)低(需要重新编译内核)

详细的设计决策请参考 架构决策记录

关键决策包括: