了解Linux/seL4中的页面表



为什么页面全局目录中的条目偏移?偏移的意义是什么(如果有的话)?

页面全局目录

地址 条目1 条目2
0000000080036000: 0x0000000000000000 0x000000000000000
0000000080036bf0: 0x0000000000000000 0x0000000000000
0000000080036c00: 0x000000002000d401 0x0000000000000000
0000000080036c10: 0x0000000000000000 0x0000000000000000
0000000080036ff0: 0x0000000000000000 0x0000000000000

为什么页面全局目录中的条目偏移?偏移的意义是什么(如果有的话)?

PGD中的条目不是偏移量,而是指向另一页表的指针。页面表中的偏移量包含在虚拟地址中。

Linux和seL4使用一个三级页面表,该表包含页面全局目录(PGD)、页面中间目录(PMD)和页面表条目(PTE)。

据我所知,这是过时的信息。我对seL4一无所知,但Linux使用4级页表。这可能还取决于像x86-64与ARM这样的体系结构。即便如此,我确信Linux在不考虑体系结构的情况下使用了4个级别,只是根据体系结构的要求丢弃了一些级别。

每个表为4096字节或0x1000。每个条目为64个字节。每个表可以有512个条目(0x200)。有些表,特别是PGD和PMD,有偏移的条目。换句话说,条目不是从表中的位置0开始,而是0,直到表的一半甚至3/4。我正试图理解为什么会这样。

这段话给了我一个提示(也许我错了),你的问题是关于x86-64体系结构的。在x86-64上,有4个级别的页表。寻呼部分由硬件实现,因为处理器的MMU将自动跨越页表以将虚拟地址转换为物理地址。它也部分由软件(操作系统)实现,因为操作系统将填充页表等。

页面表的某些部分可能为零的原因有几个。我想的是,页面表条目所代表的内存部分可能不在进程的地址空间中。这意味着用户模式进程可以访问该地址,但它将触发页面错误,因此内核应该终止该进程。

此外,如果它是一个内核页表,那么它只能是虚拟地址空间的一部分当前未被内核使用,因此可以通过在不同的条目中放置零来丢弃。有几个原因可以解释为什么页面表的某些部分为零。

可以肯定的是,在"0"之前用零填充页表总是一个好主意;给出";页面表到用户模式进程,因为否则可能会发生访问另一个进程的地址空间,这将是一个安全威胁。例如,如果用户模式进程的页面表中有一个条目没有被清零,则可能有一个进程访问该虚拟地址。它可以设置当前位(不会触发页面错误),并可以转换到另一个进程的地址空间。这将是一个漏洞。

不要忘记,页表也是内存保护,因为它们将一个进程与另一个进程隔离开来,因为页表不应该转换为属于另一个过程的地址。它们还有uservssupervisor位,允许将用户模式与内核隔离开来。

至于分页,x86-64上的4级分页方案有PML4、PGD、PDT和PT。虚拟地址如下(二进制):

Index in PML4    Index in PGD   Index in PDT    Index in PT     Offset in physical frame (12 bits)
0b000000000        000000000      000000000       000000000       000000000000

这里我只表示了48位,因为高16位是未使用的(除非启用了新处理器上存在的5级寻呼)。基本上,每9个比特是对应页面表中的索引/偏移量。12个最低有效位是物理帧中的偏移。Linux只是为其页面表提供了通用名称,因为它支持多种体系结构。Linux上的名称为PGD、PUD(Page Upper Directory)、PMD和PTE

页表条目指向另一个页表,该页表将用作使用在虚拟地址中找到的偏移量进行翻译的表。

希望这能消除任何误解!欢迎对任何内容发表评论。

相关内容

  • 没有找到相关文章

最新更新