虚拟化页面表的工作原理

时间:2018-05-14 00:03:28

标签: cpu-architecture virtual-memory

阅读虚拟化页面表概念,其中页面表的一部分放在虚拟内存中。 Wikipedia以及Patterson& Hennessy(“页面错误”一节中的5.7详细说明)说,您不将整个页表放入虚拟内存的原因是它可能导致循环页面错误。但在我看来,还有一个更基本的问题 - 你如何才能找到页面表?您似乎需要某些记录物理内存中的位置,以便通过查找页表来开始翻译过程。

为了澄清我的问题,我的困惑不是“为什么不能将所有页面表都放在内存中”。相反,它是给出的理由是“防止循环页面错误”。看起来基本原理应该是“处理器必须有一些物理地址作为起点”,无论你怎么称呼它,它都是一个物理页表。这与“循环页面错误”有什么关系?似乎更为根本。

3 个答案:

答案 0 :(得分:2)

70年代的VAX架构使用虚拟化线性页表方法来实现分页。 VAX将32位虚拟地址空间划分为四个范围:

  • P0:0x00000000 - 0x3fffffff。
  • P1:0x40000000 - 0x7fffffff。
  • S0:0x80000000 - 0xbfffffff。
  • S1:0xc0000000 - 0xffffffff。

P0(称为程序区域)和P1(称为控制区域)是用户特定的分区,S0是系统(内核)分区,S1是保留的。因此,每个进程都有自己的P0和P1映射集,但是所有进程和内核共享S0的相同映射。

请注意,虚拟地址的最高两位用于确定要访问的虚拟内存的哪个部分。每个部分(S1除外,不可用)由页表定义。特别地,P0和P1由虚拟化页表定义(页表被映射到虚拟存储器),但是S0的页表没有被虚拟化。每个页表是一个4字节页表条目的连续数组。每个页表条目无效或有效(这意味着它包含512字节页面的物理地址)。

VAX提供6个寄存器来定义页表:页表基地址寄存器和页表长度寄存器,用于虚拟地址空间P0,P1和S0的三个部分中的每一个。 P0和P1的基地址寄存器包含其两个最高有效位为10的虚拟地址。即,S0的页表包含包含P0和P1的物理地址的页表条目。这允许任何进程的P0和P1的页表驻留在主存储器或辅助存储器中。另一方面,S0的基地址寄存器包含S0页面表的物理地址。

基本上,进程的页表分为三个连续的页表,其中两个是虚拟化的,一个总是驻留在内存中。来自Wikipedia

  

有人提到创建一个包含的页表结构   虚拟地址空间中每个虚拟页面的映射都可能结束   浪费。但是,我们可以解决过多的空间问题   通过将页表放在虚拟内存中,并让虚拟内存   内存系统管理页表的内存。

     

但是,此线性页表结构的一部分必须始终保留   驻留在物理内存中,以防止反对循环页面   查找页面表中不存在的关键部分的错误   在页表中,页表中没有,等等。

S0页表是线性页表的一部分,它必须始终驻留在内存中(即,不是虚拟化的)。但为什么它必须像那样?如果S0的基地址寄存器包含虚拟地址而不是页表的物理地址,会发生什么?但在这种情况下,处理器如何计算出页表的物理基址?我们需要一些具有已知物理地址的附加数据结构,这使我们能够找出页表的物理地址。为了论证,让我们假设我们有一个存储在某个地方的数据结构。页表是否可以完全换出到二级存储?是的,如果我们有一个类似于"现在的位"那么我们可以做到这一点或"有效位"在那个数据结构中。但是,当前位设置为false,在访问任何虚拟地址的内存时发生页面错误。操作系统现在需要处理页面错误,如果它需要访问任何虚拟地址,它将再次页面错误,等等。

否则,通常情况下,如果页面错误处理程序被设计为仅使用指向始终存在的数据和代码的物理地址(通过关闭分页),则可以有效地绕过整个页面表的虚拟化。但这会使处理程序的设计大大复杂化。

将页表分区为多个连续数组,就像在VAX中完成一样,意味着页表的某些部分(S0' s)必须始终存在。

但是如果S0的页面表包含查找P0和P1页面表的条目,那么它是否也是一个有效的多级页表?要回答这个问题,让我们比较一下在VAX和32位x86中完成地址转换的方式。

在VAX转换中,虚拟页码与页表索引相同。

|31|29                  9|8       0|
------------------------------------
|  | virtual page number | offset  |
------------------------------------
|  |  page table index   | offset  |
------------------------------------

在32位x86转换中(禁用PAE和PSE),虚拟页码被分区为两级页表的两个索引。

|31                  12|11        0|
------------------------------------
|  virtual page number |  offset   |
------------------------------------
| PT 1 index|PT 2 index|  offset   |
------------------------------------

在VAX中,只访问用户页面表需要两级查找。更重要的是,使用两个不同的虚拟地址执行两次查找。另一方面,对系统页面表的访问仅需要使用单个虚拟地址进行单次查找。相反,在x86中,所有访问都需要使用相同的虚拟地址进行两级查找。

x86架构支持虚拟化的多级页表。

我们可以设计一个比两者都强大的混合页面表。如果我们使用S1分区作为第三个用户分区。我们可以为其表添加一个基地址寄存器,该寄存器包含物理地址而不是虚拟地址(如P0&和P1' s)。通过这种方式,即使进程也可以获得线性页表的潜在性能优势,同时如果操作系统内存管理器需要,仍允许进行虚拟化。我不知道有任何架构使用过这种设计。

答案 1 :(得分:2)

re:您的更新:这是表明相同要求的两种不同方式。

它是 reductio ad absurdum 参数:考虑一个CPU,其中页表指针都是虚拟地址:TLB-miss或页面错误处理程序需要采取另一个页面错误或者TLB未命中,因为它没有可以直接使用的物理地址。

这是"循环"你遇到的问题,以及为什么某个地方必须有一个物理地址,否则它就是一种捕获22 / turtles all the way down类型的情况。

答案 2 :(得分:0)

  

但在我看来,这是一个更基本的问题 - 如何找到页面表?

这是一个问题,处理器采用不同的方法。方法是为系统空间和用户空间分别设置页表。系统空间页表指定物理地址。用户空间表指定逻辑地址。因此,访问用户空间表需要通过系统空间表进行逻辑到物理转换。