综述
UVM 是 NetBSD 使用的虚拟内存系统. 与其他基于 4.4BSD 的系统如 FreeBSD 等不同, 它完全重写了4.4BSD 的 VM. 相对于 4.4BSD VM, 它有很多显著的改进. 简化了设计, 提高了效率, 特别是引入了amap, 很好地解决了COW 问题.
uvm 系统与系统 kernel 相对独立 (4.4BSD VM 基于 Mach VM, 与 Mach 微内核分离, 4.4BSD 和 NetBSD 虽然没采用微内核架构, 却也集成了这样的功能模块结构). 全部代码在代码树 src/sys/uvm 处, 下文提到的文件路径若非绝对路径 , 都是从该目录开始的路径.
核心数据结构
在 NetBSD 中, 每个进程拥有一个独立的进程空间. 这由 vmspace 结构表示, 每个 proc 接口都包含着一个执行 vmspace 的项p_vmsapce, 这个 uvm 系统与进程管理系统的接口.
vmspace 结构的声明在 uvm_extern.h, 我们看到, 除了一些审计信息之外, 它直接指向 uvm_map.h 中的 uvm_map 结构. 因此 uvm_map 结构才是代表一个地址空间, 顾名思义, 用于完成地址的映射 (mapping 功能). uvm_map 中最为重要的两项是指向硬件相关的地址空间描述结构 pmap 和 uvm_map_entry 的双向链表.
我们在下一节认真查看 uvm_map_entry 结构, 以后要经常跟它打交道. 在这里, 我们看到, 它的 start 和 end 项说明了这个 entry 映射到地址空间中的地址范围, 接下来是一个联合的指向 uvm_obj 或 sub_map 的 object 项, sub_map 是提供给内核地址空间的特殊机制, 我们很少讨论它. 可以这么说, uvm_map_entry 指向一个 uvm_obj 结构, 是该对象的映射. offset 项说明了它在 uvm_obj 中的偏移量. ps. 这都是注释写得很清楚的, 我在这里说干嘛...
我们还可以看到 aref 项, vm_aref 结构指向了一个 amap (匿名对象映射 XXX. 这个翻译准确么?), 是一种代替 4.4BSD 中多层 shadow 对象的机制.
uvm_obj, vm_amap 及一下的结构我们称为底层结构, 内存的实际分配和操作都在这以下的层面完成, 它们最终指向内存分配管理的最小单位 vm_page.
整个 uvm 的核心数据可以表示如下, vm_amap 和 uvm_obj 之间的虚线我们会在下面的章节解释. 并非真正表示指针引用关系.
vmspace
|
v
uvm_map_entry <--> vm_map_entry ...
| |
| v
| vm_pmap
|
+-----------------+
| |
v |
vm_aref |
| |
v v
vm_amap < - - - > uvm_obj
| |
v v
vm_anon ... vm_page <-> vm_page ...
|
v
vm_page
另外, 我们注意到 uvm.h 中有个 uvm 结构, 这是各种 uvm 资源和参数的集合, 系统中只存在一个 uvm 对象.
顶层映射机构 (vmspace, uvm_map, uvm_map_entry)