页表
页表是操作系统为每个进程提供私有地址空间和内存的机制,决定了内存地址的含义,以及物理内存的哪些部分可以访问。
分页硬件
用户和内核指令使用的是虚拟地址,而机器的RAM或物理内存是由物理地址索引的。
RISC-V页表硬件通过将每个虚拟地址映射到物理地址来为这两种地址建立联系。
- 在Sv39 RISC-V中,虚拟地址的前25位不用于转换;RISC-V页表在逻辑上是由一个227个页表条目组成数组,每个页表条目包含一个44位的物理页码和一些标志。分页硬件通过虚拟地址39位中的前27位索引页表,以找到改虚拟地址对应的页表条目,然后生成一个56位的物理地址,其中前44位来自页表条目中的物理页码,后12位来自原始虚拟地址。页表使操作系统能够以4096(212)字节的对齐块的粒度控制虚拟地址到物理地址的转换,这样的块称为页。
- 三级结构比单级结构更节省内存:在大范围的虚拟地址没有被映射的常见情况下,三级结构可以忽略整个页面目录。
- 三级结构的缺点是CPU必须从内存中加载三个页表条目以将虚拟地址转化为物理地址。为减少从物理内存加载页表条目的开销,RISC-V CPU将页表条目缓存在为翻译后备缓冲器(Translation Lookaside Buffer, TLB)中。
ng)- TLB是一个小的、虚拟寻址的缓存,用户组选择和行匹配的索引和标记字段是从虚拟地址中的虚拟页号中提取出来的。
- CPU产生一个虚拟地址,MMU从TLB中取出相应的PTE,MMU将这个虚拟地址翻译成一个物理地址,并将它发送到告诉缓存或主存,高速缓存或主存将所请求的数据字返回CPU。
- 当TLB不命中时,MMU必须从L1缓存中取出相应的PTE,新取出的PTE存放在TLB中,可能会覆盖一个已经存在的条目。
- TLB是一个小的、虚拟寻址的缓存,用户组选择和行匹配的索引和标记字段是从虚拟地址中的虚拟页号中提取出来的。
- 标志位
PTE_V
:指示PTE是否存在PTE_R
:控制是否允许指令读取到页面PTE_W
:控制是否允许指令写入到页面PTE_X
:控制CPU是否可以将页面内容解释为指令并执行它们PTE_U
:控制用户模式下的指令是否被允许访问页面
- 为使硬件使用页表,内核必须将根页表页的物理地址写入到
satp
寄存器中。
内核地址空间
-
QEMU模拟一台计算机,包括从物理地址
0x80000000
开始并至少到0x86400000
结束的RAM(物理内存),xv6称结束地址为PHYSTOP
. -
内核使用“直接映射”获取内存和内存映射设备寄存器,将资源映射到等于物理地址的虚拟地址。例如:
KERNBASE=0x80000000
-
trampoline page
- 映射在虚拟地址空间的顶部,用户页表具有相同的映射.一个物理页面(持有蹦床代码)在内核的虚拟地址空间中映射了两次:一次在虚拟地址空间的顶部,一次直接映射。
- 使用trampoline页表的过程如下:内核在用户页表中映射一段特定地址,该地址对应着内核中的一段特定地址,即trampoline。当发生异常或中断时,CPU会切换到内核态,并且根据中断号或异常号从内核页表中找到对应的异常处理程序的地址。异常处理程序会切换到trampoline页表,并跳转到trampoline中的指令,这些指令会重新设置用户页表,并跳转到真正的异常处理程序的地址。异常处理程序在用户页表中执行,并在处理完后再切换回内核页表。通过使用trampoline页表,可以在用户页表中安全地处理异常或中断,同时又不会破坏用户程序的虚拟地址空间。
- 映射在虚拟地址空间的顶部,用户页表具有相同的映射.一个物理页面(持有蹦床代码)在内核的虚拟地址空间中映射了两次:一次在虚拟地址空间的顶部,一次直接映射。
-
内核栈页面:每个进程都有自己的内核栈,将映射到偏高一些的地址,这样xv6在这之下就可以留下一个未映射的保护页.保护页的PTE是无效的即
PTE_V
没有设置.如果内核溢出内核栈就引发一个异常,内核触发panic
.若没有保护页,栈溢出将会覆盖其他内核内存,引发错误操作.(未映射的保护页不会浪费物理内存,只是占据了虚拟地址空间的一段靠后的地址,但是并不映射到物理地址空间)