在 x86_64 Long 模式下运行 32 位代码时,Linux 内核如何排列页表?

在 x86_64 Long 模式下运行 32 位代码时,Linux 内核如何排列页表?

x86_64 架构允许在长模式下运行时本地运行 32 位代码。因此添加了一个名为“兼容模式”的子模式。现在内存管理模式通过下表来计算物理地址:

PML4 (Linux: PGD) -> PDPT (Linux: PUD) -> PD (Linux: PMD) -> PT -> physical page

上面提到的每个表都由 512 个条目组成,大小为 64 位,因此您需要 9 位作为每个表的索引,并需要 12 位作为偏移量,添加到从 PT 检索到的最后一个地址。总计为 48 位。现在看来很明显,使用 32 位地址无法实现相同的效果。
其他人已经尝试解释这是如何完成的(这里或者这里)但在我看来这是不对的。那里解释说 PDPT 和 PD 各只有一个条目,但这种行为会给我的理解带来一些麻烦。
MMU 将从地址中取出前 9 个最高有效位来获取 PDPT 的地址。现在PDPT中只有一个条目,但MMU有严格的程序,将从地址中取出接下来的9位作为索引。现在,512 个案例中只有一个会选择第一个条目。 PD 也存在同样的问题。
这并不是我看到的唯一问题。如前所述,32 位不足以完成完整的转换,因此必须以某种方式跳过某些表。

希望我可以解释我的问题并且有人可以帮助我。

答案1

x86-64 中长模式的兼容性子模式不会影响分页,其功能与 64 位长模式中相同。 32 个隐式零位被插入到馈入分页单元的虚拟地址的位位置 63-32 中。您只需要设置页表,将这些零位映射到有效的内容,就像您链接到的第一个问题中的答案所解释的那样。看2.1.4.1 长模式内存管理AMD64 架构程序员手册第 1 卷:应用程序编程 (PDF)

相关内容