文章

总结:MMU -- 包括 TLB 以及 Table Walk Unit ,以及内存 Page Table

1. MMU 结构以及工作过程

大多数使用MMU的机器采用内存分页机制,虚拟地址空间以页(Page)为单位,相应的,物理地址空间也被划分为页帧(Frame)页帧必须与保持相同的大小,通常为4KB,对于大页,页帧可以是2MB或1GB。大页一般用于服务器,用于系统分配大量数据,减少缺页中断的发生。

MMU通过页表(Page Table)将虚拟地址映射到物理地址,页表存储在主存中,由系统内核创建及管理。

CPU with MMU

MMU由两部分组成:TLB(Translate Look-aside Buffer),以及Table Walk Unit

  1. TLB (Translation Lookaside Buffer):缓存最近使用的 VAPA 的映射;
  2. Table Walk Unit:如果TLB没有命中CPU发出的VA,则由Table Walk Unit根据位于物理内存中的页表(Page Table)完成VAPA的查找。

在上述过程中,如果Table Walk Unit没有找到对应的PA,则向CPU发出Page fault中断,CPU处理缺页中断(具体见后面章节描述)。

MMU的工作过程图示:

MMU Work Process

CPU发出的VA由两部分组成:VPN(Virtual Page Number) + offseet。对应的,转换之后的物理地址也有两部分:页框号PFN(Pyysical Frame Number) + offset

VPN to PFN

1.1 从VAPA,MMU处理流程图

MMU VA to PA Process

2. 页表结构

现代CPU一般采用四级页表结构。以32位地址空间的二级页表为例,CPU发出的虚拟地址被拆分分为:页目录(Page Directory)、页表(Page Table)、页内偏移(Page Offset)三级(以4k为例,即12位)。

VPN的最高10位用于索引页目录,紧接的10位用于索引页表索引,最低12位为页内偏移地址。拆分结构如下图所示:

Page Table Structure

2.1 MMU查找过程

MMU先根据一级页表的物理地址和一级页表Index去一级页表中找PTE,PTE中的地址不再是最终的物理地址,而是二级页表的物理地址。

根据二级页表物理地址和二级页表index去二级页表中找PTE,此时PTE中的地址才是真实的物理地址。

根据此物理地址和offset找到最终的物理内存地址。

MMU Lookup Process

使用二级页表的好处是如果一级页表中的某一个PTE没有命中,那这一PTE对应的整个二级页表就不存在。

2.2 进程页表与 Address Space ID

操作系统会为每个进程分配一个页表,该页表使用物理地址存储。当进程使用类似malloc等需要映射代码或数据的操作时,操作系统会在随后马上修改页表以加入新的 物理内存

每次切换进程都需要进行TLB清理。这样会导致切换的效率变低。为了解决问题,TLB引入了ASID(Address Space ID)ASID的范围是0-255ASID由操作系统分配,当前进程的ASID值被写在ASID寄存器(使用CP15 c3访问)TLB在更新页表项时也会将ASID写入TLB

MMU在查找TLB时, 只会查找TLB中具有相同ASID值TLB行。且在切换进程时,TLB中被设置了ASIDTLB行不会被清理掉,当下次切换回来的时候还在。所以ASID的出现使得切换进程时不需要清理TLB中的所有数据,可以大大减少切换开销

3. 页表项(PTE)TLB 中的标志位

在进程的虚拟内存空间中,每一个虚拟内存页在页表中都有一个PTE与之对应,在32位系统中,每个PTE占用4个字节大小,其中保存了虚拟内存页背后映射的物理内存页的起始地址,以及进程访问物理内存的一些权限标识位。

PTE in Page Table

由于内核将整个物理内存划分为一页一页的单位,每个物理内存页大小为 4K,所以物理内存页的起始地址都是按照 4K 对齐的,也就导致物理内存页的起始地址的后 12 位全部是 0,我们只需要在PTE中存储物理内存地址的高 20 位就可以了,剩下的低 12 位可以用来标记一些权限位。

PTE flags

一些标志位的含义如下:

  • P(0):映射的物理内存是否在内存中。值为0表示可能被换出,需要从磁盘中读取。此时,其他bit位存放的是物理内存页在磁盘中的位置;
  • R/W(1):值为0表示该物理页只读,针对该页面的写操作触发page fault异常。比如,使用fork创建子进程之后,父子进程内存空间完全一样,页表中的内容也是一样的,父子进程中的PTE均指向同一物理内存。此时,内核将父子进程中的PTE均修改为只读的,并将父子进程共同映射的这个物理内存引用计数+1。当子进程需要进行写操作时,在内核的page fault异常处理时,发现这个物理页面的引用计数大于1,说明是多进程共享同一个物理内存,将进行写时拷贝(Copy On Write, COW),内核为子进程重新分配一个物理页,复制原有物理页中的内容到新物理页,减少物理页面的引用计数,并修改子进程PTE中的R/W标志位。
  • PCD(2)Page Cache Disable,表示PTE指向的物理内存页面中的内容,是否可以被缓存到Cache中。在SOC异构处理器共享同一块物理内存时,可以使用PCD创建禁止CachePTE
  • PWT(3): Page Write-Through,表示PTE指向的CPU Cache中的内容,是直接写入物理内存(Write-Through),还是在Cache-line被中的内容被替换时写入物理内存(Write-Back)。

4. 缺页处理过程

  • 处理器要对虚拟地址VA进行访问。
  • MMUTLB没有命中,通过TWU遍历主存页表中的PTEA(PTE地址)。
  • 主存向MMU返回PTE
  • PTE中有效位是0,MMU触发一次异常,CPU响应page fault异常,运行相应的处理程序。
  • 缺页异常处理程序选出物理内存中的牺牲页,若这个页面已经被修改,将其换出到硬盘。
  • page fault处理程序从硬盘中加载新的页面,并更新内存中页表的PTE。
  • page fault处理程序返回到原来的进程,再次执行导致缺页的指令。CPU将引起缺页异常的虚拟地址重新发给MMU。由于虚拟页面现在缓存在主存中,主存会将所请求的地址对应的内容返回给cache和处理器。

Page Fault Process

参考

本文由作者按照 CC BY 4.0 进行授权