序言
过去一个月,由于我对 ArceOS 的架构理解较少,为了快速掌握 ArceOS 的架构,Unikernel 和 宏内核,我的主要目标改进 oscamp,为其完善对 x86_64 的支持。同时还做了对内核组件 x86_rtc 说明文档和测试的完善。
最直接的收获有两点:
- Unikernel 思想 —— “用户态就是内核的一部分” 的最小可信边界,让我重新审视传统多进程操作系统里“内核/用户”硬隔离的成本。
- 宏内核工程学 —— 模块划分、内核线程、系统调用网关、设备驱动归一化,这些都在 Starry/ArceOS 的设计里有了“先行者版本”。
工作记录
第一周
为了快速掌握 ArceOS 的架构,Unikernel 和 宏内核,我选择了改进 oscamp,为其完善对 x86_64 的支持这一项工作。并开始了对 x86_64 的学习。
第二、三周
主要是做代码工作,以下是一些总结
RISC‑V 是通过 scause
+ stval
;x86‑64 要区分 Exception Class(#PF/#UD)与 IRQ Vector,且栈布局不一样。
对 x86_64 的支持这一项工作需要完成以下的功能实现:
- 改进 context.rs,保存相关的寄存器,并完善 context_switch 和 enter_uspace。
- 保存/恢复的寄存器集对齐 SysV x86‑64 调用约定:
RBX RBP R12‑R15
+CR3
+RFLAGS
;FPU/AVX
延后到 lazy fp 任务。 context_switch(old, new)
= 保存旧任务栈顶 → 恢复新任务栈顶 →iretq
;为支持SMP
,加了core::arch::asm!("swapgs")
保证每 CPU 的 GS 基址切换。- 进入用户态 (
enter_uspace
):手动构造iretq
帧:SS|RSP|RFLAGS|CS|RIP
,再写CR3 = user_pml4
; 关中断→加载帧→开中断→iretq
。
- 保存/恢复的寄存器集对齐 SysV x86‑64 调用约定:
- 改进 trap.S
- IDT 256 项:
0x20
时钟、0x80
软中断、0x0E
#PF……全部指向统一的trap_entry
;硬中断通过 APIC 自动切到 IST[0] emergency stack 防止内核栈溢出。 trap.rs
根据向量号派发到handle_page_fault / handle_irq / handle_syscall
。
- IDT 256 项:
- 改进 syscall.rs 和 syscall.S
- 选
SYSCALL/SYSRET
而非INT 0x80
;入口先swapgs
用 GS 保存/恢复用户栈。 - 按 SysV ABI
RAX
=nr,RDI RSI RDX R10 R8 R9
传六参 —— 在汇编里把寄存器序列化到栈,统一传给x86_syscall_handler()
。 - 退出路径:恢复通用寄存器 →
swapgs
→sysretq
- 选
第四周
对内核组件 x86_rtc 说明文档和测试的完善。
repo
未来展望
- Transparent HugePages:复用前期完成的巨页 API,引入
khugepaged
合并线程。 - vDSO:把高频
clock_gettime
胶水放到用户态,加速 Sys‑API。