深入淺出記憶體管理-Linux核心頁表
阿新 • • 發佈:2018-12-16
核心頁表實現
新版本的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將設定為不可用。