Linux 分页模型是抽象的吗?

Is the Linux paging model an abstraction?

我目前正在阅读 了解 Linux 内核第三版,我正在阅读有关内存寻址的第 2 章。首先,本书涵盖了 32 位分页、PAE 32 位和 PSE(我们在这里谈论的是 x86)。更具体地说,线性地址的剖析以及tables、偏移量等的位是什么……我开始对Linux中的分页模型感到困惑。有一段时间,这本书在谈论目录、table 和线性地址的偏移位(PAE 的 PDPT table),接下来我被扔进了“Linux”分页的世界.现在使用 Linux 分页,他们谈论具有 table 和偏移量的全局、上层和中层 tables?我根本看不出 x86 MMU 分页与这个新的 Linux 模型有什么关系。如果 MMU 负责翻译(分页)地址,为什么内核也需要这种分页模型?看起来内核应该把它留给 MMU。如果有人能详细说明为什么内核有这个,那就太好了!

我知道 MMU 必须根据内核管理的 table 来转换地址。因此,MMU 负责地址转换(来自内核上进程 运行 的内存访问),但内核不是!那么为什么我们有这个全局的、上层的和中间的 tables 以及 table 和偏移量的东西?

或者这个 Linux 分页模型可能比我想象的更抽象!也许这个内核页面 table 的想法并不是真正的 table 而是一组内核宏,指定内核必须维护的页面 directories/tables 的许多级别的属性!例如,PGD_SIZEPUD_SIZE 和其他 SIZE 宏(以及 SHIFTMASK 宏)指定分页级别的不同属性.基于这些宏(当然还有其他的宏)内核能在内存中生成正确的页面tables吗?这个Linux分页模型可以根据具体的架构调整SHIFT宏(更具体地说是线性地址在具体架构上的位布局)?

At one moment the book was talking about directory, table, and offset bits of a linear address (PDPT table for PAE) and next I was thrown into the world of "Linux" paging. Now with the Linux paging they talk about Global, Upper, and Middle tables with table and offset?

是的......这很快就会变得非常混乱。 Intel手册讲到分页的时候,page table不同层级的条目叫做:

  • PML5E = 页面映射级别 5 条目
  • PML4E = 页面映射级别 4 条目
  • PDPTE = 页目录指针 Table 条目
  • PDE = 页面目录项
  • PTE = 页码 Table 条目

从以上名称可以推断,x86 最多支持 5 层页面 tables(在现代处理器上)。根据处理器的能力,可以在任何给定的处理器上使用不同的分页模型,例如没有 PAE 分页的 32 位使用 2 级页面 tables:我们只有 PDE 和 PTE,CR3 指向页面目录).可以设置和使用更多页面 table 级别,在这种情况下,我们开始讨论 PDPTE(用于 3 级分页)、PML4E(4 级分页)和 PML5E(5 级分页)。

当然,页面 table 在大多数 CPU 体系结构中几乎是一个无处不在的概念,而不仅仅是 x86。然而,每个体系结构都有其特定的方式来命名不同级别的页面 table 条目。 Linux 支持许多不同的体系结构,因此它为页面 table 条目提供了一些“通用”名称:

  • pgd_t = 页面全局目录条目
  • p4d_t = 页面 4 级目录条目
  • pud_t = 页面上层目录条目
  • pmd_t = 页面中间目录条目
  • pte_t = 页面 Table 条目

现在这可能会让人感到困惑。 Intel 和 Linux 的命名约定之间存在重大区别。无论页面 table 的级别数如何,对于 Linux 页面全局目录 始终 代表根(因此 pgd_t 始终代表 highest-level 个条目):

  • 5级分页,Intel名称与Linux名称的对应关系很简单:pgd_t:PML5E, p4d_t:PML4E, pud_t :PDPTE, pmd_t:PDE, pte_t:PTE.
  • 对于 4 级分页,我们有 pgd_t:PML4E,p4d_t 是不必要的,因此它实际上成为 pgd_t 的别名(在 5 级分页支持之前,根本就没有 p4d_t
  • 类似地,对于 3 级分页,我们有 pgd_t:PDPTE,对于 2 级分页,我们有 pgd_t:PDE。

If the MMU is in charge of translating (paging) addresses, why does the kernel need this paging model as well? It just seems like the kernel should just leave it up to the MMU.

嗯,是的,内核 确实 将工作留给了 MMU。我们在这里谈论的只是命名约定。 Linux 没有在 MMU 已经使用的模型之上使用另一种分页模型,它只是有一种不同的、更通用的命名方式,仅此而已。


Maybe the idea of this kernel page table is not really a table but a set of kernel macros specifying the properties of the many levels of page directories/tables that the kernel has to maintain!

[...]

Based on these macros (of course there are other macros) the kernel can generate the correct page tables in memory? This Linux paging model can adjust the SHIFT macros based on the specific architecture (more specifically the bit layout of linear addresses on the specific architecture)?

是的,是的,是的。你说对了。这正是这种命名抽象背后的基本原理。内核仅以一种方式调用事物,但会根据底层架构调整宏(例如PMD_OFFSET)、类型(例如pmd_t)和逻辑。