ax-cpu
路径:
components/axcpu类型:库 crate 分层:组件层 / ISA 与特权级抽象层 版本:0.3.0-preview.8文档依据:当前仓库源码、Cargo.toml、README.md、src/lib.rs、各架构mod.rs/asm.rs/context.rs/init.rs/trap.rs
ax-cpu 是 ArceOS 系栈中位于 ax-hal 之下、位于原始 CPU 指令之上的一层 ISA 抽象库。它负责把不同架构下的特权寄存器、异常现场、任务上下文切换、页表根寄存器、TLB 刷新和部分早期 CPU 初始化统一成可供内核/HAL 调用的接口。它不是页表库,也不是板级支持包,而是“面向 CPU 本身”的底层抽象层。
架构设计
设计定位
ax-cpu 处理的是“CPU 相关但又不能散落在平台代码里”的部分,包括:
- 特权寄存器读写
- trap/exception 入口与现场表达
- 任务上下文切换
- 页表根寄存器切换与 TLB 刷新
- AArch64/LoongArch 等架构上的 MMU 初始化辅助
它与相邻层的边界应明确区分:
axplat:负责“在什么时机调用这些 CPU 原语”ax-page-table-entry/ax-page-table-multiarch:负责“页表内容是什么”ax-cpu:负责“CPU 如何装载页表根、如何刷 TLB、如何响应 trap”
模块结构
src/lib.rs 的结构非常清楚:
- 根层提供
trap公共入口 uspace_common在开启uspace时提供共享用户态辅助- 通过
cfg_if!在编译期只选择一个目标架构实现
当前支持:
x86_64riscv32/riscv64aarch64loongarch64
1.3 各架构模块共性
虽然各架构目录不同,但整体模式很统一:
| 模块 | 作用 |
|---|---|
asm.rs | 中断开关、页表根寄存器读写、TLB 操作、线程指针等汇编原语 |
context.rs | TrapFrame、TaskContext、可选 TLS/FP 状态 |
init.rs | 早期 CPU 初始化,如 trap 基址、MMU、EL 切换 |
trap.rs / trap.S | 异常/中断入口与 Rust 分发 |
uspace.rs | 用户态相关 trap 语义和返回原因 |
这种设计让“架构差异”被限制在每个子目录内部,而上层调用面尽量一致。
1.4 trap 与异常分发模型
ax-cpu 在根层提供了 trap 注册与分发基础设施。关键特征有两个:
- 使用
linkme风格的分布式切片注册 handler - 对
IRQ与PAGE_FAULT两类关键入口做统一分发
这说明它不只是“汇编入口集合”,而是已经定义了 CPU 级异常分发协议。
1.5 关键数据结构
TrapFrame
表示异常/中断进入内核后的现场。不同架构字段不同,但共同承担:
- 保存通用寄存器
- 保存返回 PC / 状态寄存器
- 提供调试和回溯基础
TaskContext
用于协作式上下文切换。它保存的是任务切换最关键的一组状态,而不是完整 trap 现场。启用不同 feature 时,还会携带:
- TLS 相关寄存器
- 浮点/SIMD 状态
- 用户页表根
PageFaultFlags
这类页错误语义最终来自 ax_page_table_entry::MappingFlags,说明 ax-cpu 并不自己重新定义一套访问权限语言,而是复用整个页表栈的公共位语义。
1.6 典型架构差异
x86_64
- 建 GDT/IDT
- 读写
CR3 - 初始化 per-CPU 辅助状态
- 用户态路径涉及 syscall MSR 等
RISC-V
- 使用
satp stvec负责 trap 入口- 在
uspace场景中设置 SUM 等权限位