📖
🎥 B 站博文精講視頻:點擊鏈接,配合視頻深度學習
四級頁表通俗講解與實踐(以 64 位 ARM Cortex-A 為例)
本文面向希望徹底理解現代 64 位架構下四級頁表的開發者,結合 ARM Cortex-A 系列處理器,詳細講解虛擬地址到物理地址的映射全過程。結構清晰,細節完整,結合真實虛擬地址與物理地址舉例,適合學習與實踐。
一、四級頁表是什么?
1. 概念引入
- 在現代 64 位處理器(如 ARMv8-A Cortex-A 系列)中,內存管理單元(MMU)將 虛擬地址(VA) 轉換為 物理地址(PA)。
- 為了高效管理大空間內存,ARMv8-A 采用四級頁表結構,層層映射。
- 頁表本質是多級查找的“索引表”,每一級根據虛擬地址的一部分找到下一級頁表或物理頁框。
2. 四級頁表的結構
-
每一級頁表存放固定數量的表項,每個表項保存下一級頁表的物理基地址及權限/屬性等。
-
常見配置下:
- 每級索引 9 位,512 個表項(2? = 512)
- 最后 12 位為頁內偏移(支持 4KB 頁大小)
-
總共:9 + 9 + 9 + 9 + 12 = 48 位虛擬地址
| LVL0 | LVL1 | LVL2 | LVL3 | Offset |
|------|------|------|------|--------|
| 9bit | 9bit | 9bit | 9bit | 12bit |
|<---------- 48 位虛擬地址 ------------>|
-
在 ARM 文檔/代碼中,四級頁表常稱為:
- Level 0 table(L0)
- Level 1 table(L1)
- Level 2 table(L2)
- Level 3 table(L3)
- 每一級頁表項均為 8 字節(64 位),其中高位用于存儲下一級物理基地址。
二、虛擬地址如何拆分?(以 Cortex-A 64 位為例)
假設一個 48 位虛擬地址:
0x0000_1234_5678_9ABC
拆解如下:
位段 | 位數 | 含義 | 示例值 |
---|---|---|---|
47 ~ 39 | 9 | L0 索引(表項) | 0x0000000000000002 |
38 ~ 30 | 9 | L1 索引 | 0x0000000000000046 |
29 ~ 21 | 9 | L2 索引 | 0x00000000000000B0 |
20 ~ 12 | 9 | L3 索引 | 0x0000000000000123 |
11 ~ 0 | 12 | 頁內偏移(4KB 頁) | 0x00000000000009ABC |
(示例值以實際拆分得到的二進制高/低位為例,便于理解)
三、查表過程:虛擬地址到物理地址的詳細流程
1. 分解虛擬地址
- 每一級用虛擬地址的 9 位做索引,查找該級表的第 N 項。
- 最后 12 位為頁內偏移。
2. 四級查找過程(ARM 通用流程)
- L0 表基地址(由 TTBR0/TTBR1 寄存器給出,物理地址)
- 用 L0 索引查表,得到 L1 表物理地址(通常 4KB 對齊)
- 用 L1 索引查表,得到 L2 表物理地址
- 用 L2 索引查表,得到 L3 表物理地址
- 用 L3 索引查表,得到最終物理頁框地址(高位)
- 用頁內偏移補齊低 12 位,拼出完整物理地址
3. 圖示結構
VA [47:39] [38:30] [29:21] [20:12] [11:0]| | | | |v v v v v+-------------------------------------------------+| L0 | L1 | L2 | L3 | Offset |+-------------------------------------------------+
四、完整舉例:Cortex-A 64 位四級頁表查找過程
例子設定
假設有如下參數:
- TTBR0_EL1 = 0x4000_0000(L0 頁表物理基地址)
- 虛擬地址 VA = 0x0000_1234_5678_9ABC
1. 拆分虛擬地址
- L0 索引 = (VA >> 39) & 0x1FF = (0x0000_1234_5678_9ABC >> 39) & 0x1FF = 0x2
- L1 索引 = (VA >> 30) &
F = (0x0000_1234_5678_9ABC >> 30) & 0x1FF = 0x46 - L2 索引 = (VA >> 21) & 0x1FF = (0x0000_1234_5678_9ABC >> 21) & 0x1FF = 0xB0
- L3 索引 = (VA >> 12) & 0x1FF = (0x0000_1234_5678_9ABC >> 12) & 0x1FF = 0x123
- Offset = VA & 0xFFF = 0x9ABC
2. 查找過程
-
Step 1:L0(TTBR0_EL1 + 2 × 8)
- L0表的第2項,假設內容為 0x0000_6000_0003 (L1表物理基地址 0x6000_0000)
-
Step 2:L1(0x6000_0000 + 0x46 × 8)
- L1表的第70項,內容為 0x0000_7F00_0003 (L2表物理基地址 0x7F00_0000)
-
Step 3:L2(0x7F00_0000 + 0xB0 × 8)
- L2表的第176項,內容為 0x0000_9000_0003 (L3表物理基地址 0x9000_0000)
-
Step 4:L3(0x9000_0000 + 0x123 × 8)
- L3表的第291項,內容為 0x0000_A200_3003 (物理頁框基地址 0xA200_3000)
-
Step 5:加上 offset
- 物理地址 = 0xA200_3000 + 0x9ABC = 0xA200_CABC
3. 總結查表過程
- 虛擬地址 VA = 0x0000_1234_5678_9ABC
- 物理地址 PA = 0xA200_CABC
- 每一級查表都用虛擬地址的 9 位,+ 8 字節(64 位表項大小)
- 終極目標:虛擬地址的頁內偏移直接對應物理地址的低 12 位,高位來自頁表遞歸查找結果。
五、總結與實戰要點
- 四級頁表讓大內存空間管理變得高效且靈活,支持細粒度權限和屬性控制。
- 只要搞懂“每一級 9 位索引 + 最后 12 位偏移”,四級頁表的本質其實非常直觀。
- ARM Cortex-A(v8 64 位)架構四級頁表結構和 x86_64 類似,易于類比和移植理解。
- 實際開發中,如需分析虛擬地址映射,結合 TTBR0/TTBR1、頁表物理地址、虛擬地址拆分即可快速定位。
小結:四級頁表是一種多級查找機制,核心在于“索引分段 + 遞歸查表”,只要學會虛擬地址的二進制拆分與索引對應,每一級表項的物理地址拼接,配合工具觀測,就能輕松掌握虛擬到物理的完整映射流程。
視頻教程請關注 B 站:“嵌入式 Jerry”