C 什么';Xv6中P2V、V2P宏背后的机制是什么

C 什么';Xv6中P2V、V2P宏背后的机制是什么,c,operating-system,xv6,C,Operating System,Xv6,我知道在虚拟地址变成物理地址的过程中有一种映射机制 与下面一样,线性地址包含三个部分 页面目录索引 页表索引 抵消 以下是示例: 现在,当我在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 c

我知道在虚拟地址变成物理地址的过程中有一种映射机制

与下面一样,线性地址包含三个部分

  • 页面目录索引
  • 页表索引
  • 抵消
  • 以下是示例:

    现在,当我在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如何能正常工作?

    V2P和P2V宏的功能并不比您想象的多。它们只是减法和加上KERNBASE常量,标记为2GB

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

    具体而言,在XV6中,流程的虚拟空间结构(通过适当的映射)正在构建,如下所示:

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

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

    这一决定的动机也有明确规定:

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

    换句话说,由于内核使所有页表都将2GB虚拟映射到0物理(直到PHYSTOP),因此我们可以很容易地找到2GB以上虚拟地址的物理地址。 例如:可以很容易地找到虚拟地址0x1000000的物理地址:它是0x00001000,我们只需减去2GB,因为这就是我们将它映射为的方式

    这种“变通方法”可以帮助内核轻松地进行转换,例如,用于构建和操作页表(其中需要计算物理地址并将其写入内存)

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

    这种安排的一个缺陷是xv6无法 使用超过2 GB的物理内存


    我建议您在“进程地址空间”标题下的XV6注释中阅读更多关于这种方式的内容

    V2P和P2V宏的功能并没有超出您的想象。它们只是减法和加上KERNBASE常量,标记为2GB

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

    具体而言,在XV6中,流程的虚拟空间结构(通过适当的映射)正在构建,如下所示:

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

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

    这一决定的动机也有明确规定:

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

    换句话说,由于内核使所有页表都将2GB虚拟映射到0物理(直到PHYSTOP),因此我们可以很容易地找到2GB以上虚拟地址的物理地址。 例如:可以很容易地找到虚拟地址0x1000000的物理地址:它是0x00001000,我们只需减去2GB,因为这就是我们将它映射为的方式

    这种“变通方法”可以帮助内核轻松地进行转换,例如,用于构建和操作页表(其中需要计算物理地址并将其写入内存)

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

    这种安排的一个缺陷是xv6无法 使用超过2 GB的物理内存


    我建议您在“进程地址空间”标题下的XV6注释中阅读更多关于这种方式的内容

    我猜这是在设置
    KERNBASE
    时完成的,我猜这是在设置
    KERNBASE