Xv6中P2V,V2P宏背后的机制是什么

时间:2018-04-28 06:55:23

标签: c operating-system xv6

我知道虚拟地址如何变成物理的映射机制。

如下所示,线性地址包含三个部分

  1. 页面目录索引
  2. Page Table index
  3. 偏移
  4. 以下是插图:

    Page Translation Picture

    现在,当我在memorylayout.h中查看Xv6的源代码时

    #define V2P(a) (((uint) (a)) - KERNBASE)
    #define P2V(a) (((void *) (a)) + KERNBASE)
    
    #define V2P_WO(x) ((x) - KERNBASE)    // same as V2P, but without casts
    #define P2V_WO(x) ((x) + KERNBASE)    // same as P2V, but without casts
    

    如果不执行地址转换过程,V2P或P2V如何正常工作?

1 个答案:

答案 0 :(得分:1)

V2P和P2V宏的功能并不像你想象的那么多。它们只是减去并添加KERNBASE常量,标记为2 GB。

您似乎正确理解了MMU的硬件映射机制。 映射规则由每个进程页表保存。这些表格形成了流程的虚拟空间。

具体来说,在XV6中,正在构建进程的虚拟空间结构(通过适当的映射),如下所示:virtual address space layout

如上图所示,XV6专门构建了进程的虚拟地址空间,以便2GB - 4GB虚拟地址(分别)映射到0到PHYSTOP物理地址。正如XV6官方评论中所解释的那样:

  

Xv6包含内核在每个进程的页表中运行所需的所有映射;   这些映射都出现在KERNBASE之上。它映射虚拟地址KERNBASE:KERNBASE + PHYSTOP   到0:PHYSTOP。

还明确了这一决定的动机:

  

这种映射的一个原因是这样的   内核可以使用自己的指令和数据。另一个原因是内核有时候   需要能够写入给定的物理内存页面,例如何时   创建页表页面;让每个物理页面都出现在可预测的虚拟页面上   地址使这很方便。

换句话说,因为内核使所有页表都将2GB虚拟映射到0物理(并且高达PHYSTOP),我们可以很容易地找到超过2GB的虚拟地址的物理地址。 例如:虚拟地址0x10001000的物理地址很容易找到:它是0x00001000,我们只减去2GB,因为我们将它映射为。

这"解决方法"可以帮助内核轻松完成转换,例如,构建和操作页表(需要计算物理地址并将其写入内存)。

当然,以上"解决方法"不是免费的,因为这会浪费宝贵的虚拟地址空间(2GB),因为现在每个物理地址至少已经有1个虚拟地址。即使我们永远不会使用它。离开整个虚拟地址只留下2GB的实际进程(总共4GB,因为我们使用32位来计算地址)。这也在XV6官方评论中得到了解释:

  

这种安排的缺点是xv6无法制作   使用超过2 GB的物理内存

我建议你在"流程地址空间"下的XV6评论中阅读更多关于这种方式的内容。头。 XV6 Commentary