ARM Linux页面表布局

3

我已经阅读了多篇关于这个主题的文章,包括以下文章,但对我来说仍然有些模糊:

http://elinux.org/Tims_Notes_on_ARM_memory_allocation

ARM Linux kernel page table

Linux kernel ARM Translation table base (TTB0 and TTB1)

ARM硬件在L1转换表中有4096个每个4字节的条目。每个条目将内存中的1MB区域进行转换。在第二级别上,它有256个每个4字节的条目。每个第二级别的条目将内存中的4KB页面进行转换。 因此,根据这个规则,任何虚拟地址必须被分成12-8-12来映射到上述方案。

但在32位ARM Linux侧,这个分配是11-9-12。其中L1转换表由2048个条目组成,每个条目为8字节。这里将两个4字节的条目结合在一起,并将指向的第二级转换表按顺序排列在内存中,因此在第二级中,不是256而是512个条目。此外,由于Linux内存管理希望使用与ARM不同的各种标志,所以我们为Linux页面表定义了512个附加条目(每个二级HW页面表一个)。

现在的问题是,Linux不强制执行PGD/PMD/PTE大小(但强制页面大小为4K。因此将PAGE_SHIFT设置为12),那么为什么要选择11-9-12布局(即为PGD选择11位,为HW PTE选择9位)。 这样做只是为了确保512HW +512Linux PTE对齐到页面边界吗?

如果有人能详细解释这个分配背后的逻辑,那就太好了....

2个回答

3
正如您所说,在ARM短描述符格式中,每个二级页表的大小为1KB。即使加上相关的影子页表,也只有2KB,这意味着为二级表分配的每个页面的50%将完全浪费。
Linux通过成对分配一级条目来“假装”部分大小为2MB,而不是硬件实际的1MB,以便相应的一对二级表可以保持在单个页面中,并避免浪费,从而使页面表内存的管理真正简单。

为什么Linux不能假装段大小为4MB,并将四个二级页表保留在一个页面中? - nagla
1
它可能可以这样做,但那样它也需要在某个地方跟踪第二页,以获取4个影子页表。这可能不值得麻烦。 - Notlikethat
“pretend” 有点误导。通用的 MMU 层被告知 L1 条目为 2MB。ARM MMU 代码知道物理硬件。挑战在于将 ARM MMU 硬件(在 ARM CPU 家族之间不同)映射到通用的 Linux MMU 代码/API。它不能使用 4MB 的区块,因为需要管理/模拟“脏”、“年轻”和“访问”位的附加细节。 - artless noise
@artlessnoise "通用MMU层被告知L1条目为2MB..." - 确实;架构代码"表现出(节大小为2MB)的样子,而实际上并非如此"。我不明白这有什么误导的地方... - Notlikethat
是的,但“假装”并没有回答“如果有人能详细解释这个除法背后的逻辑将会很好”的问题,而且它肯定不是计算机科学术语(无论如何感谢您提供的字典参考)。顺便说一句,我投了你的半个答案。 - artless noise

2

ARM Linux和脏位应该有所有的答案。主要是,PTE表具有额外的信息来模拟位,从而产生您观察到的布局。

我认为一个误解是L2表占用的内存与它映射的内存不同。您必须为L2表分配物理内存,并使其对称(4K大小),使其与所有页面相同。现在,这个4k页面可以是四个ARM MMU L2页表。然而,我们需要一些附加信息来模拟Linux通用MMU代码所需的年轻访问位。因此,Linux L2(PTE目录)的布局如下:

  1. Linux PTE [n]
  2. Linux PTE [n+1]
  3. ARM PTE [n]
  4. ARM PTE [n+1]
在L1级别,每个条目都成对出现(n / n+1),以便它指向上面的第3和第4项。 pgtable-2level.h文件对布局进行了详细注释(应该适用于您的Linux版本)。
参见:ARM MM上的Tim笔记          ARM Linux内核中的页面表项(PTE)描述符

感谢大家宝贵的反馈。因此,由于Linux需要额外的管理位,并且将ARM硬件和Linux PTE排列在一个4KB页面内,我们只需要引用一个页面。否则,我们将不得不访问两个页面,一个用于硬件,一个用于Linux PTE。但是,既然内核页表永远不会被交换出去,那真的很重要吗? - nagla
还有一件事,对我来说有点不清楚。ARM硬件将始终使用硬件页表,这是否意味着Linux的页表只能由Linux用于内部使用?假设在我的代码中,我引用了某个内存位置,并且正确的页表已经由硬件和Linux进行设置,那么当CPU访问此地址时,ARM硬件将自动使用硬件页表,并根据硬件页表中的权限允许或禁止访问。问题是,在这种情况下,Linux的页表有什么作用...它们似乎是无用的? - nagla
1
Linux主要使用Linux PTE值;这就是为什么它们排在首位的原因。有一个提交操作,CPU MMU层将把Linux PTE转换为hw PTE。一些相关问题暗示了这一点。交换不重要(MMU使用物理地址,但CPU使用虚拟地址来管理它们),因此它们必须实际存在。然而,当它们被分组在一起时,TLB访问将减少。正如前面所说,这减少了代码复杂性。所有内容都处理4k页面。通用MM/MMU代码使用Linux PTE值。Linux内核需要它们。CPU需要hw PTE。 - artless noise

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接