ax-memory-set
路径:
memory/memory_set类型:库 crate 分层:组件层 / 地址区间集合与映射元数据层 版本:0.4.1文档依据:当前仓库源码、Cargo.toml、README.md、src/lib.rs、src/area.rs、src/backend.rs、src/set.rs
ax-memory-set 是 ArceOS/StarryOS/Axvisor 这条内存管理链上的“区间集合与操作骨架”。它不直接实现页表,也不直接决定物理页如何分配,而是围绕“若干不重叠地址区间”和“这些区间应如何映射”提供统一的数据结构与操作流程。可以把它理解为一层抽象的 mmap/munmap/mprotect 元数据引擎:上层负责地址空间语义,下层 Backend 负责真正操作页表。
架构设计
设计定位
该 crate 解决的是一个非常具体的问题:
- 如何维护一组不重叠的虚拟地址区间
- 如何对这些区间执行 map/unmap/protect
- 如何把“区间操作”与“页表实现”解耦
因此它属于“内存区间元数据层”,而不是“完整虚拟内存子系统”。
模块结构
| 模块 | 作用 | 关键内容 |
|---|---|---|
lib.rs | 顶层导出和错误定义 | MappingError、MappingResult |
backend.rs | 后端抽象 | MappingBackend |
area.rs | 单个区间对象 | MemoryArea<B> |
set.rs | 多区间集合管理 | MemorySet<B> |
tests.rs | 回归测试 | MockBackend 与典型操作路径 |
1.3 MappingBackend:与具体页表解耦的关键
MappingBackend 是整个 crate 的设计中心。它把真正的页表操作下沉到实现方,只保留三个核心动作:
mapunmapprotect
并通过关联类型把三类关键信息延后绑定:
AddrFlagsPageTable
这意味着 ax-memory-set 完全不需要知道:
- 地址究竟是
VirtAddr还是GuestPhysAddr - flags 究竟是普通页权限还是嵌套页表权限
- 页表究竟是宿主页表、进程页表还是 EPT/NPT 封装
1.4 MemoryArea<B>:单段连续映射描述
MemoryArea<B> 由三部分组成:
va_rangeflagsbackend
它描述“一段连续地址区间以某种权限和某种后端方式被管理”。这里最关键的设计是:一个区间不仅有范围和权限,还有自己的 backend 实例。这使同一地址空间中的不同区域可以在逻辑上挂接不同后端策略。
MemoryArea 提供的高阶能力包括:
map_areaunmap_areaprotect_areasplitshrink_leftshrink_right
后面三个操作是 munmap/mprotect 这类区间切分逻辑的核心。
1.5 MemorySet<B>:以 BTreeMap 组织的不重叠区间集合
MemorySet<B> 的内部结构是:
- 以区间起始地址为 key 的
BTreeMap
选择 BTreeMap 的原因很直接:
- 需要有序管理区间
- 需要支持按地址查找最近的前驱区间
- 需要支持扫描空洞、寻找可用区域
它公开的核心操作是:
overlapsfindfind_free_areamapunmapprotectclear
1.6 关键算法主线
map
map 的典型路径为:
- 检查参数与区间合法性
- 检查是否与已有区间重叠
- 若允许覆盖,则先做区间级
unmap - 调用
backend.map()真正建立映射 - 将新区间插入
BTreeMap
unmap
unmap 的难点在于区间几何关系。已有区间可能:
- 完全落在待删除范围内
- 与左边界相交
- 与右边界相交
- 被待删除范围切成左右两段
源码通过 split、shrink_left、shrink_right 来处理这些情况。
protect
protect 与 unmap 的结构很像,只是它不是删除区间,而是可能将原区间拆成最多三段:
- 左侧保留原权限
- 中间替换成新权限
- 右侧保留原权限
这说明 ax-memory-set 并不是简单“存个区间表”,而是明确承担了区间切分与重组算法。
1.7 一个重要边界:不处理页错误
这点必须明确:
ax-memory-set不包含handle_page_faultMappingBackend也不要求实现页错误处理
页错误处理通常发生在更高层,例如:
ax-mm在自己的Backend中扩展出 fault 语义axaddrspace在嵌套页表路径中处理缺页
ax-memory-set 本身只负责维护“区间元数据”和“区间级页表操作流程”。
核心功能
功能概览
- 维护一组不重叠地址区间
- 对区间执行 map/unmap/protect
- 支持查找指定地址所在区间
- 支持查找满足对齐和大小要求的空闲区间
- 通过
MappingBackend与不同页表实现解耦
使用场景
| 场景 | 角色 |
|---|---|
| ArceOS 进程/内核地址空间 | 区间元数据层 |
StarryOS mmap / munmap | 区间切分与保护变更骨架 |
| Axvisor 访客物理地址空间 | GPA 区间组织与后端映射调度 |
2.3 错误模型
MappingError 只定义三类错误:
InvalidParamAlreadyExistsBadState
这体现了该 crate 的风格:它只暴露区间管理需要知道的最小失败原因,不把后端复杂状态直接泄露到接口层。
当启用 ax-errno feature 时,还可以桥接到更通用的错误体系。
依赖关系
直接依赖
| 依赖 | 作用 |
|---|---|
memory_addr | 提供 AddrRange 与 MemoryAddr 抽象 |
ax-errno(可选) | 把 MappingError 映射到统一错误类型 |
主要消费者
os/arceos/modules/axmmos/StarryOS/kernelmemory/axaddrspace