圖文詳解 Linux 分頁機制!

分頁機制是 80x86 內存管理機制的第二種機制,分段機制用於把虛擬地址轉換爲線性地址,而分頁機制用於把線性地址轉換爲物理地址。分頁機制可以用於任何一種分段機制,也可以理解爲先有分段機制纔有分頁機制,這是由於歷史原因,分段機制要比分頁機制更輕,先出現的分段後出現的分頁。

處理器的分頁機制用於把線性地址劃分成一個個的頁面,這些劃分成頁面的線性地址會被映射到物理空間的頁面上。

我們知道分段的保護措施有兩種,一種是利用任務之間的保護;一種是利用內存段和寄存器之間的保護。

分頁機制有幾種頁面級的保護措施,分段機制和保護措施可以和分頁機制的保護措施一起使用,也可以使用分頁機制的保護措施替換分段機制的保護。

比如分頁機制可以在頁面的基礎上加強讀 / 寫保護。另外,在頁面單元上,分頁機制還提供了用戶和超級用戶兩級保護。

分頁機制可以通過 CR0 控制寄存器的 PG 這個標誌位來判斷是否開啓分頁機制;如果 PG = 1 ,則表示啓用分頁操作,處理器會使用本節描述的機制將線性地址轉換爲物理地址。如果 PG = 0,則表示禁用分頁機制,此時分段產生的線性地址會被直接用作物理地址。

分段機制和分頁機制還有一個區別就是:分段機制可以在任意可變長度的內存上進行操作,而分頁機制只能對固定大小的頁面(內存塊)進行操作。分頁機制把線性和物理地址空間都劃分成頁面。線性地址空間中的頁面都可以映射在物理地址空間內,如下圖所示。

80x86 使用 4K (2 ^ 12) 字節固定大小的頁面,每個頁面均是 4KB,並且對齊於 4KB 地址邊界處。這表示分頁機制會把 4GB 劃分成爲以 4KB 爲基礎的頁面,共劃分 1M(1048576) 個,線性地址的低 12 bit 位可以直接作爲頁內偏移量,也可直接作爲物理地址的低 12 位。

現在我們知道線性地址空間會經過分頁機制映射到物理內存空間上,這是一個正常能夠映射到的情況,如果映射不到怎麼辦?也就是說包含線性地址空間的頁面不在物理內存中怎麼辦?此時處理器就會產生一個頁錯誤異常。頁錯誤異常的處理程序會讓操作系統從磁盤中把相應的頁面加載到物理內存中。當頁面加載到物理內存中後,會從異常處理程序中返回,使得處於異常指令的位置繼續向下執行指令。

頁錯誤異常是分頁機制實現換入換出過程中出現頻次非常高的一種異常機制,它就好像 bug 一樣如影隨形,而且頻繁的頁面換入換出操作會很耗費處理器資源,所以爲了減少頻繁換入換出的操作,採用了一種局部性原理的方式:把經常訪問的頁目錄和相關頁 "保存" 起來,這裏採用了一種硬件實現,即轉換查找緩衝區(Translation Lookaside Buffer)。有了 TLB,處理器會先從 TLB 中查找相關頁,TLB 中不存在的頁纔會從內存中進行讀取,此時的 TLB 相當於是內存的一個副本。

頁表結構

頁表中每個頁表項的大小爲 32 位,其中 20 位來存放物理基地址,剩餘的 12 位存放可用於存放頁面是否存在等屬性信息。如果線性地址索引的頁表項被標註爲存在,則表示該項有效,我們可以從中取得物理地址;如果線性地址索引的頁表項不存在,那麼訪問物理頁面就會產生異常。

下面是一個線性地址到物理地址的變換過程圖。

可以看到,80x86 使用了兩級頁,這是爲了減少頁的數量所設計的,因爲雖然每個頁字節是 4K,共有 2 ^ 20 (1MB)個頁,總共佔據 4MB 大小,但實際上應用程序一次用不到這麼多頁,會造成資源浪費,所以採用了一種分層的設計方式。

第一級稱爲頁目錄(page directory),它被存放在 1 個 4K 頁面中,因爲一共有 2 ^ 10 次方(1 MB)個頁目錄,每個目錄是 4 字節,所以是在一個 4K 頁面中。線性地址的最高十位(22 - 31 位)用作一級表(頁目錄)中的索引來訪問二級表。

第二級稱爲頁表(page table),它和頁目錄一樣,也是佔據一個頁面,最多含有 1K 個 4 字節的頁表。頁表項會存儲 20 位的物理地址,線性地址中的 12 - 21 位作爲頁表的索引,用於獲取含有 20 位物理地址的頁表項。頁表項的 20 位物理基地址和線性地址中的低 12 位一起合成最終的 32 位物理地址。

頁表項結構

現在我們知道線性地址的低 12 位和頁表存儲的 20 位可以合成物理地址,頁表項除了能夠存儲地址外,還有一些其他的屬性,下面是頁表項的結構圖。

這裏需要特別注意的是,頁目錄的結構和頁表的結構是一樣的,只不過他倆描述的主體不一樣,一個描述的是頁目錄,一個描述的是頁表。

根據上面字段的描述,可以看到頁目錄和頁表項中的 P 位爲分頁技術的虛擬存儲提供了必要的標識,若線性地址空間中的頁面存在於物理內存中,那麼對應的表項 P = 1,並且該表項中含有相應的物理地址。頁面不在物理內存中的表項 P = 0 。如果程序訪問物理內存中不存在的頁面,處理器就會產生一個缺頁異常。此時操作系統就會利用這個異常把缺少的頁面從磁盤調入內存,把相應的物理地址放在表項中,返回程序繼續執行引起異常的指令並且設置 P = 1。

A 和 D 這兩個標誌位是實現虛擬存儲的基礎,這兩個標誌位可以定期檢測指定的頁面是否訪問過並且是否可以讀寫,從而判斷哪些頁面可以移出到磁盤。比如一個頁面從磁盤讀入內存後,它的 D 標誌位爲 0 ,那麼當頁被移除磁盤時,它的 D 位還是 0 的話,就可以判斷這個頁面無需調入磁盤。D = 1 表示頁面已經被修改過,就需要將其寫回到磁盤上。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/xyoj9uSNq3M8i-aCrmf6qA