axvisor_api
路径:
virtualization/axvisor_api类型:库 crate 分层:组件层 / Hypervisor 公共 API 契约层 版本:0.1.0文档依据:当前仓库源码、Cargo.toml、README.md、README.zh-cn.md、src/lib.rs、axvisor_api_proc与os/axvisor/src/hal/mod.rs
axvisor_api 是 Axvisor 多 crate 架构中的“窄腰层”。它试图解决的问题不是页表、设备或 vCPU 本身,而是:在不把每个组件都做成泛型 HAL trait 大杂烩的前提下,如何把宿主 hypervisor 必须提供的能力统一暴露给 arm_vcpu、riscv_vcpu、arm_vgic、axvm 等组件。
架构设计
设计定位
从源码和 README 看,axvisor_api 的设计目标非常明确:
- 定义一组所有 hypervisor 组件都能直接调用的普通 Rust API
- 这些 API 本身不由组件实现,而由最终的 hypervisor 或宿主侧 glue 层统一实现
- API 定义与实现通过
ax-crate-interface连接,而不是通过泛型参数层层向上传播
这使它在架构上更接近“组件公共服务总线”,而不是传统意义上的 HAL trait 集合。
模块结构
axvisor_api 本体的模块划分很清晰:
| 模块 | 作用 | 关键内容 |
|---|---|---|
memory | 宿主内存能力 | 页帧分配/释放、连续页分配、PA/VA 转换、AxMmHalApiImpl、PhysFrame |
time | 时间与定时器 | tick/nanos/time 转换、定时器注册与取消 |
vmm | VM 管理 API | 当前 VM/vCPU ID、vCPU 数量、向 vCPU 注入中断 |
host | 宿主全局信息 | CPU 数量 |
arch | 架构相关扩展 | 当前仅 AArch64 的虚拟中断注入与 host GIC 信息 |
__priv | 宏展开私有支撑 | ax-crate-interface 的内部重导出 |
除此之外,还有独立的过程宏 crate:
| 模块 | 作用 |
|---|---|
axvisor_api_proc | 实现 api_mod 与 api_mod_impl,把模块中的 extern fn 转换成定义/调用/实现代码 |
1.3 api_mod / api_mod_impl 机制
这是本 crate 的核心创新点。
定义侧:#[api_mod]
例如:
#[api_mod]
pub mod memory {
extern fn alloc_frame() -> Option<PhysAddr>;
}
过程宏会把它转换成:
- 可直接调用的普通
pub fn - 一组基于
ax-crate-interface的def_interfacetrait - 对应的
call_interface!调用桥
调用方因此只需要像调用普通函数那样使用 axvisor_api::memory::alloc_frame()。
实现侧:#[api_mod_impl(...)]
实现方在 os/axvisor 中使用:
#[axvisor_api::api_mod_impl(axvisor_api::memory)]
mod memory_api_impl {
extern fn alloc_frame() -> Option<HostPhysAddr> { /* ... */ }
}
过程宏会把它转成对相应 ax-crate-interface trait 的唯一实现。
这种机制的意义在于:
- 组件方只依赖
axvisor_api - 实现方只需要在最终宿主环境注册一次
- 避免在每个 crate 上携带层层泛型 HAL 参数
1.4 与 ax-crate-interface 的关系
axvisor_api 不是从零实现这套动态绑定能力,而是在 ax-crate-interface 之上做了更友好的语法包装。
因此可以把它理解为:
ax-crate-interface:底层机制axvisor_api_proc:面向 Axvisor 场景的语法糖axvisor_api:具体公共 API 的定义集合
1.5 当前 API 面的真实边界
从当前源码看,已经稳定暴露出的 API 主要是五组:
memory
alloc_frame()alloc_contiguous_frames()dealloc_frame()dealloc_contiguous_frames()phys_to_virt()virt_to_phys()
此外还在模块内部定义了:
AxMmHalApiImplPhysFrame = axaddrspace::PhysFrame<AxMmHalApiImpl>
也就是说,memory 模块不仅暴露函数,还顺手把这套 API 接成了 axaddrspace::AxMmHal 可直接消费的形式。
time
current_ticks()ticks_to_nanos()nanos_to_ticks()register_timer()cancel_timer()
以及几个纯函数包装:
current_time_nanos()current_time()ticks_to_time()time_to_ticks()
vmm
current_vm_id()current_vcpu_id()vcpu_num()active_vcpus()inject_interrupt()notify_vcpu_timer_expired()
需要注意的是,当前 os/axvisor 的实现中:
active_vcpus()仍是todo!()notify_vcpu_timer_expired()仍是todo!()
因此这两个接口当前在契约层存在,但实现层尚未闭环。
host
get_host_cpu_num()
arch
当前只在 aarch64 下暴露:
hardware_inject_virtual_interrupt()read_vgicd_typer()read_vgicd_iidr()get_host_gicd_base()get_host_gicr_base()
这意味着 arch 是真正的架构扩展面,而不是“所有平台统一 API”。