ax-plat-riscv64-qemu-virt 技术文档
路径:
components/axplat_crates/platforms/axplat-riscv64-qemu-virt类型:库 crate 分层:组件层 / 可复用基础组件 版本:0.3.1-pre.6文档依据:Cargo.toml、README.md、src/lib.rs、src/boot.rs、src/init.rs、src/mem.rs、src/console.rs、src/time.rs、src/irq.rs、src/power.rs
ax-plat-riscv64-qemu-virt 是 axplat 在 QEMU RISC-V virt 机型上的具体实现。它把 SBI、PLIC、UART、Goldfish RTC、固定物理内存布局以及多 hart 启动这些板级细节,整理成 axplat 约定的 InitIf、MemIf、ConsoleIf、TimeIf、PowerIf 和可选 IrqIf 接口,是 RISC-V 平台进入 ArceOS 运行时的第一层板级 glue。
1. 架构设计分析
1.1 设计定位
这个 crate 的核心职责不是实现通用 HAL,而是把 virt 板级假设固化为一套可被 ax-hal 和运行时稳定调用的接口:
- 向下,它直接面对 SBI、PLIC、16550 UART、Goldfish RTC 和固定的 MMIO/内存布局。
- 向上,它并不直接服务应用,而是通过
axplattrait 接口被ax-hal、ax-runtime和平台示例内核复用。 - 在启动期,它负责最早期页表、栈、MMU 与主核/从核入口桥接;在运行期,它继续承担时间、中断、控制台、电源和内存区间查询。
因此,ax-plat-riscv64-qemu-virt 应被理解为“RISC-V virt 板级 bring-up 实现”,而不是“可移植的架构抽象层”。
1.2 内部模块划分
src/lib.rs:平台入口总装。定义config、rust_entry、rust_entry_secondary,并汇总各个*IfImpl。src/boot.rs:最早期启动路径。定义启动栈、静态 Sv39 页表、_start/_start_secondary与 MMU 打开流程。src/init.rs:实现InitIf,把早期 trap、串口、时间初始化和后期 per-CPU 初始化串接起来。src/mem.rs:实现MemIf,定义物理内存范围、MMIO 区间、内核地址空间范围以及phys_to_virt/virt_to_phys。src/console.rs:实现ConsoleIf,通过uart_16550访问 NS16550 MMIO 串口。src/time.rs:实现TimeIf,提供单调时间、可选墙钟偏移和可选 one-shot timer。src/irq.rs:在irqfeature 下实现IrqIf,负责 PLIC 初始化、scause分发、IPI 和定时器处理。src/power.rs:实现PowerIf,提供关机、CPU 数查询和可选 HSM 启动从核逻辑。
1.3 关键数据结构与全局对象
BOOT_STACK:主核启动栈,位于.bss.stack。BOOT_PT_SV39:最早期静态页表,用 1GiB 大页把低地址与高半部虚拟地址窗口映射起来。UART:LazyInit<SpinNoIrq<MmioSerialPort>>,早期串口与运行期控制台共用。PLIC:irq打开时的全局 PLIC 对象。IRQ_HANDLER_TABLE:按 IRQ 号索引的处理函数表。TIMER_HANDLER/IPI_HANDLER:定时器和 IPI 的注册入口。RTC_EPOCHOFFSET_NANOS:启用rtc时,用 Goldfish RTC 标定的墙钟偏移。