X86 关于多级分页中页表漫游的详细信息

X86 关于多级分页中页表漫游的详细信息,x86,paging,virtual-memory,X86,Paging,Virtual Memory,为了简单起见,我将用一个具体的例子来解释我的问题。请注意,我对基本概念感兴趣 考虑两级分页方案,即我们有一页目录表和多页表。为了将虚拟地址转换为物理地址,我们首先使用虚拟地址的n个最高有效位来索引页面目录表。从那里我们得到一个页表的地址。使用虚拟地址的剩余位,我们索引此页表以查找数据的物理地址 现在我想知道以下几点:页面目录表是存储页面表的虚拟地址还是物理地址 如果它存储页表的物理地址,那么这意味着我们无法将任何页表分页到磁盘。但是为了使用多级分页来节省存储,我们需要能够将分页表分页到磁盘。因此

为了简单起见,我将用一个具体的例子来解释我的问题。请注意,我对基本概念感兴趣

考虑两级分页方案,即我们有一页目录表和多页表。为了将虚拟地址转换为物理地址,我们首先使用虚拟地址的n个最高有效位来索引页面目录表。从那里我们得到一个页表的地址。使用虚拟地址的剩余位,我们索引此页表以查找数据的物理地址

现在我想知道以下几点:页面目录表是存储页面表的虚拟地址还是物理地址

如果它存储页表的物理地址,那么这意味着我们无法将任何页表分页到磁盘。但是为了使用多级分页来节省存储,我们需要能够将分页表分页到磁盘。因此,我们在页面目录表中使用虚拟地址。但这意味着在索引页面目录表之后,我们首先必须转换获得的虚拟地址,这需要另一个页面表遍历(在该页面表遍历中,我们再次必须转换虚拟地址等)。因此,这似乎并不奏效


显然我错过了一些重要的事情。我很想了解这背后的概念以及实际实现。或者让我知道在哪里可以找到这些信息

现代分层分页设计中的页面目录包含页面表的物理地址。例如,显示了32位x86的格式:PDE的高20位是页面对齐的物理地址,低12位包括有效条目的标志。基本上与指向最终物理页面的PTE条目相同

但是当清除
p
resent位时,条目的其余部分可用于保存操作系统想要的任何内容,例如虚拟地址或交换空间的偏移量。页面漫游硬件在看到它不存在后立即停止,因此页面漫游失败。(如果不是错误推测的结果,TLB未命中将成为操作系统以某种方式处理的
#PF
页面错误。)

可以设计一种分页体系结构,其中页面目录的某些条目(但不是全部)包含页面表的虚拟地址。例如,可以将分页视为具有两个级别,其中包含页表的地址和长度的三个寄存器对可以一起视为页目录。其中两个条目包含虚拟地址,第三个条目包含物理地址。可以使用物理地址页表解析虚拟地址页表

包含物理地址的条目保存虚拟地址空间的内核分区的转换,并且只能在内核模式下访问。包含虚拟地址的条目是每个进程的,需要在每个上下文开关上更改。这与x86分页设计不同,在x86分页设计中,每个进程都有自己的页面目录,并且必须在每个进程中复制内核映射。这就是说,x86中的每个上下文开关上只需更改一个寄存器(CR3)。此外,VAX中微小的“页面目录”使页面表的内存开销优于平面页面时间,但仍不如x86中使用的平衡层次页面表。另一个折衷办法是,32位x86中的所有虚拟地址都必须经过两个级别的4KB页内存内转换,而VAX中的内核虚拟地址只需要一个级别的内存内转换,因为第一个级别保存在少数寄存器中。这对于x86中相对较大的页面目录是不可行的

但是为了使用多级分页来节省存储,我们需要能够将分页表分页到磁盘

通常,使页表可分页对于减少分页结构的内存开销不是很重要。虚拟内存分配器应该(并且确实)尝试从页面表的最低可用级别开始,尽可能密集地分配内存,更高级别页面目录中的许多项根本不“存在”,而不是指向一个包含1024个项(4KB)的完整表,这些项的当前位已被清除。尽管在分配和解除分配的很长一段时间内,页面表在最内部的级别上可能会变得稀疏,但在其他级别上可能会变得密集。这是分页页表非常有用的地方,尤其是在可用或剩余物理内存总量不足的平台上。在Windows上,页面表可以在除顶层以外的所有级别进行分页。Linux页表不可分页

(或者使用hugepages:页面目录项实际上是将4MB虚拟内存转换为连续的4MB物理内存。因此,再次避免使用4KB页面表空间,但将虚拟内存映射而不是不存在。)


分页表可以在x86上完成,使用PDE上的当前位,并将其剩余部分作为元数据来区分不应该映射还是分页

在x86上,您必须让页面错误处理程序手动遍历页面表(或在其他结构中查找),以确定它是否确实是无效的页面错误,或者是否到达了逻辑上应该存在的不存在的页面目录项,并且需要分页页面表的一部分,并让任务重试其内存访问

(这可能会导致从4k页面到实际数据的另一个页面错误。)请注意,硬件页面漫游比页面错误要便宜得多,并且在无序执行期间,可能会在“后台”推测性地发生


将分配分组到与现有分配相同的4M区域(或在x86-64、2M或1G上),可以避免需要新的4k页PTE