版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/rikeyone/article/details/84640042
内核页表实现
新版本的Linux内核代码中支持4级映射,那么一个虚拟地址是包含有如下几个部分:
PGD:Page Global Directory,L0级别页表
PUD:Page Upper Directory,L1级别页表
PMD : Page Middle Directory,L2级别页表
PTE : Page Table Entry,L3级别页表
PageOffset:in-page offset,除去上面的页表项后剩余的虚拟地址。
内存映射设计虚拟地址和物理地址的映射,必须要平台的支持,在具体实现的时候,这部分也是跟平台息息相关,这4级页表是会按照平台支持的情况来确定,如果我们的平台恰好支持4级页表映射,那么就向上面介绍的那样分为5个部分,假如只支持3级映射,那么内核中的PUD/PMD可以配置为相等,假如平台只支持2级页表映射,那么PUD/PMD/PTE可以配置为相等。
aarch64平台支持
aarch64是ARMv8架构实现,该类型处理器最大可以支持48根地址线,最大4级映射,那就可以寻址2的48次方的地址空间,也就是256TB,理论上完全可以做到64根地址线,这样就能够寻址更大的空间了,但是目前可能是觉得256T够用,为避免更大的复杂度,所以选择48根寻址线。这是该架构最大支持的配置,当然我们也可以配置它为更低级别的配置。它支持的配置方式如下所示:
AArch64 Linux memory layout with 4KB pages + 3 levels:
Start End Size Use
-----------------------------------------------------------------------
0000000000000000 0000007fffffffff 512GB user
ffffff8000000000 ffffffffffffffff 512GB kernel
AArch64 Linux memory layout with 4KB pages + 4 levels:
Start End Size Use
-----------------------------------------------------------------------
0000000000000000 0000ffffffffffff 256TB user
ffff000000000000 ffffffffffffffff 256TB kernel
AArch64 Linux memory layout with 64KB pages + 2 levels:
Start End Size Use
-----------------------------------------------------------------------
0000000000000000 000003ffffffffff 4TB user
fffffc0000000000 ffffffffffffffff 4TB kernel
AArch64 Linux memory layout with 64KB pages + 3 levels:
Start End Size Use
-----------------------------------------------------------------------
0000000000000000 0000ffffffffffff 256TB user
ffff000000000000 ffffffffffffffff 256TB kernel
由这个表可以看出,配置不同的页表级别以及不同的page size,那么处理器能寻址的范围就不同。一般情况下这里的配置和系统memory设计有关,我们需要根据项目实际情况配置对应的内核选项。
虚拟地址划分
我们常见的4KB+4Level配置的地址划分如下:
Translation table lookup with 4KB pages:
+--------+--------+--------+--------+--------+--------+--------+--------+
|63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0|
+--------+--------+--------+--------+--------+--------+--------+--------+
| | | | | |
| | | | | v
| | | | | [11:0] in-page offset
| | | | +-> [20:12] L3 index
| | | +-----------> [29:21] L2 index
| | +---------------------> [38:30] L1 index
| +-------------------------------> [47:39] L0 index
+-------------------------------------------------> [63] TTBR0/1
假如配置为4KB+3Level,那么相比与上面就少了一个级别:
Translation table lookup with 4KB pages:
+--------+--------+--------+--------+--------+--------+--------+--------+
|63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0|
+--------+--------+--------+--------+--------+--------+--------+--------+
| | | | | |
| | | | | v
| | | | | [11:0] in-page offset
| | | | +-> [20:12] L3 index
| | | +-----------> [29:21] L2 index
| | +---------------------> [38:30] L1 index
| +-------------------------------> [47:39] NC
+-------------------------------------------------> [63] TTBR0/1
可以看到它的[47:39]是不用来寻址的,那么它总的寻址范围就减少了,总共只能寻址512GB 。这种也是我们很常用的一种配置。
最后介绍64KB+3Level的地址划分如下:
Translation table lookup with 64KB pages:
+--------+--------+--------+--------+--------+--------+--------+--------+
|63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0|
+--------+--------+--------+--------+--------+--------+--------+--------+
| | | | |
| | | | v
| | | | [15:0] in-page offset
| | | +----------> [28:16] L3 index
| | +--------------------------> [41:29] L2 index
| +-------------------------------> [47:42] L1 index
+-------------------------------------------------> [63] TTBR0/1
当然同理,64KB+2Level,上面的L1 index将设置为不可用。