萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 作業系統 >  >> Linux 教學

讀核日記(六):Linux 保護模式下的兩級分頁機制詳解

承接前文分段機制,本文深入分析 80386 保護模式下的分頁機制。分頁是實現虛擬記憶體的關鍵,將 4GB 線性位址空間劃分為 4KB 頁框,透過兩級頁表將線性位址轉換為實體位址,並由 TLB (Translation Lookaside Buffer) 加速轉換過程。

一、 控制暫存器與分頁啟用

CR0 控制暫存器關鍵位元:

  • PE (Protection Enable, bit 0):1 = 保護模式,0 = 實模式。
  • PG (Paging, bit 31):1 = 啟用分頁,0 = 停用分頁 (線性位址 = 實體位址)。

啟用分頁需先載入 CR3 (頁目錄基址),再置 PG=1。CR2 儲存導致頁錯誤的線性位址,供處理程式使用。

二、 兩級頁表結構設計動機

32 位元線性位址空間 = 4GB。若採用單級頁表,每頁 4KB,共 1M 頁。每個頁表項 (PTE) 4 字節 → 頁表大小 4MB,且需連續實體記憶體,極不實用。

Linux 採用 兩級頁表:

  • 頁目錄 (Page Directory):1K 項目 (10 位元索引),大小 4KB,恰好佔滿一頁。
  • 頁表 (Page Table):每個頁目錄項指向一張頁表,每張頁表 1K 項目 (10 位元索引),大小 4KB。

總頁表項數 = 1K × 1K = 1M,覆蓋 4GB 空間,但只需為實際使用的區域分配頁表,極大節省記憶體。

三、 線性位址結構與轉換流程

32 位元線性位址劃分為三段:


 31          22 21          12 11           0
+--------------+--------------+--------------+
|  目錄索引(10) |  頁表索引(10) |  頁內偏移(12) |
+--------------+--------------+--------------+

轉換步驟

  1. 頁目錄查找:CR3 存放頁目錄實體基址。取線性位址 [31:22] 作為索引,乘 4 加上 CR3 基址 → 頁目錄項 (PDE) 實體位址。讀取 PDE,取得頁表實體基址 (PDE[31:12] << 12)。
  2. 頁表查找:取線性位址 [21:12] 作為索引,乘 4 加上頁表基址 → 頁表項 (PTE) 實體位址。讀取 PTE,取得頁框實體基址 (PTE[31:12] << 12)。
  3. 形成實體位址:頁框基址 + 線性位址 [11:0] (頁內偏移) = 最終 32 位元實體位址。

PDE / PTE 旗標位 (關鍵)

  • Present (P, bit 0):1 = 頁面在實存,0 = 頁面不在實存 (觸發頁錯誤)。
  • Read/Write (R/W, bit 1):1 = 可讀寫,0 = 唯讀。
  • User/Supervisor (U/S, bit 2):1 = 用戶態可存取,0 = 僅核心態。
  • Accessed (A, bit 5):CPU 存取時自動置 1。
  • Dirty (D, bit 6, 僅 PTE):寫入時自動置 1,供換出判斷。
  • Page Size (PS, bit 7, 僅 PDE):1 = 4MB 大頁 (Pentium+),0 = 4KB 標準頁。

四、 頁面快取:TLB (Translation Lookaside Buffer)

TLB 是 CPU 內部的全相聯/組相聯快取,儲存近期使用的「線性頁號 → 實體頁框」映射。命中時直接獲得實體頁框,省去兩級頁表查詢。Context Switch 時需刷新 TLB (載入新 CR3 自動刷新),或使用 invlpg 指令刷新單一條目。

五、 Linux 核心中的頁表管理

  • pgd_t、pmd_t、pte_t:核心定義的頁目錄項、頁中間目錄項 (三級/四級架構)、頁表項類型,封裝架構差異。
  • pgd_offset(mm, addr)、pmd_offset()、pte_offset():三級/四級通用查找巨集。
  • mk_pte(page, prot)、pte_mkwrite()、pte_mkclean():PTE 屬性構建與修改。
  • __get_free_pages()、alloc_page():頁框分配器 (Buddy System)。

六、 總結

兩級分頁機制以 4KB 頁框為基本單位,透過頁目錄 + 頁表層級間接映射,實現稀疏位址空間的高效管理。TLB 硬體快取消除查表開銷,使虛擬記憶體效能接近實體記憶體。理解位址拆分、PDE/PTE 旗標、頁錯誤處理流程,是掌握 Linux 記憶體管理、除錯頁錯誤、開發核心模組的基石。

copyright © 萬盛學電腦網 all rights reserved