MIT 6.S081 页表

发布时间 2023-07-03 20:34:23作者: zwyyy456

Paging hardware

总的来说,Xv6 的虚拟内存到物理内存的映射方式与 x64 是一致的,都是使用页表来进行映射。区别在于,Xv6 只使用了三级页表,而 x64 则是使用四级页表,另外,二者的页表层级的命名也有区别,对 Xv6 来说,最高级的页表是 L3(其地址存放于寄存器 satp 中)。

每个 page table 含有 512 个 page table entry,而每个 page table entry 的大小是 8KB,因此一个 page table 占据的大小正好是 4KB,即一个 VP 的大小!

VMZ31LnYWRb8TUy

标志位可以说是顾名思义,除了这个 dirty?(留待之后处理)

Kernel address space

Xv6 中,每个进程都有属于自己的地址空间,以及一个全局唯一的描述内核地址空间的 page table,(kernel page table)。

内核内存布局:

QEMU 模拟了一台带 RAM(物理内存)的电脑,该 RAM 的起始地址是 $\text{0x80000000}$ ,结束地址至少是 $\text{0x86400000}$(该地址在 Xv6 中被定义为 PHYSTOP),这里的地址说的都是物理地址。

QEMU 会将设备接口以内存映射的控制寄存器暴露给系统软件,这些寄存器地址映射的内存都是在 $\text{0x80000000}$,即系统要访问这些设备,都是通过 $\text{0x80000000}$ 以下的物理地址直接访问,但通过这样的物理地址访问设备就不会经过 RAM 了。

内核空间的虚拟地址是直接映射到物理地址的,例如 KERNBASE=0x80000000,虚拟地址和物理地址都是这个值,可以理解为虚拟地址等于物理地址。

但是有几个内核虚拟地址不是直接映射的,如下图所示:

  • trampoline page(蹦床页面),它映射在虚拟地址空间的顶部,user page table 具有相同的映射,即不论 kernel page table 还是 user page table,trampoline page 的虚拟地址都是在虚拟地址空间的顶部;
  • kernel stack page,每个进程都有自己的 kernel stack,会映射到虚拟地址空间中比较高的那个 kernel stack,这样可以利用到 kernel stack 下方的那个 guard page。Guard page is invalid!PTE_V 没有设置)。因此,一旦 kernel stack 发生溢出,就会发生异常。

9iXhFnAN2DIozBx

trampoline page 是 r-x 的,kernel stack 是 rw- 的。

从图上来看,其实只有 kernel data 和 kernel text 是直接映射的。

Code: creating an address space

关于操作 page table 和地址空间的代码主要位于 kernel/vm.c 中。

通过函数 walk 找到虚拟地址对应的 PTE 以及最终的物理地址(相当于之前 csapp 的虚拟内存那一章提到的 page walk)。