为什么页面全局目录中的条目偏移?偏移的意义是什么(如果有的话)?
页面全局目录
地址 | 条目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
页表条目指向另一个页表,该页表将用作使用在虚拟地址中找到的偏移量进行翻译的表。
希望这能消除任何误解!欢迎对任何内容发表评论。