核心如何定址交換分區文件上的交換記憶體頁?
交換分區不包含結構化文件系統。核心不需要它,因為它將記憶體頁面儲存在標記為交換區域的分區上。由於交換區域中可能有多個記憶體頁面,當程序請求將其頁面載入到記憶體中時,核心如何定位每個頁面。讓我們解釋一下,看看 Devuan OS 的交換分區的標題:
#define SWAP_UUID_LENGTH 16 #define SWAP_LABEL_LENGTH 16 struct swap_header_v1_2 { char bootbits[1024]; /* Space for disklabel etc. */ unsigned int version; unsigned int last_page; unsigned int nr_badpages; unsigned char uuid[SWAP_UUID_LENGTH]; char volume_name[SWAP_LABEL_LENGTH]; unsigned int padding[117]; unsigned int badpages[1]; };
因此,當
mkswap
為分區執行命令時,這就是放置在該分區上的內容,即交換標頭。現在,讓我們有一個場景,其中程序 A 的記憶體頁面被交換,因此交換區域中有一個記憶體頁面。當然,交換區中可能有很多記憶體頁。現在,程序 A 需要訪問被交換的記憶體頁。程序 A 告訴核心,可以給我交換的記憶體頁嗎?核心說:當然,我親愛的朋友。核心在交換分區中尋找程序 A 的記憶體頁面。由於交換分區不是複雜的結構(不是文件系統),核心如何知道如何在交換分區中定位程序 A 的特定記憶體頁面。
也許核心在某個地方儲存了那些交換頁面的扇區地址,所以當一個程序請求它的記憶體頁面時,核心知道在交換分區中查找的位置,從分區中讀取記憶體頁面並將其載入到記憶體中。
交換僅在給定引導期間有效,因此所有跟踪資訊都保存在記憶體中。換入和換出頁面完全由核心處理,並且對程序是透明的。基本上,記憶體被分成頁面,在頁表中跟踪;這些是每個 CPU 架構定義的結構。當一個頁面被換出時,核心將其標記為無效;因此,下次任何嘗試訪問該頁面時,CPU 都會出錯,這將導致核心中的處理程序被呼叫;恢復頁面內容是這個處理程序的責任。
在 Linux 中,有一個
swap_info
描述每個交換設備或文件的結構。在該結構中,aswap_map
將記憶體頁面映射到交換設備或文件中的塊。當一個頁面被換出時,核心將swap_info
索引和swap_map
偏移量儲存在相應的頁表條目中,這允許它在必要時在磁碟上找到該頁面。(所有受支持的架構在其頁表中都為此提供了足夠的空間,但存在限制——例如,可用空間意味著 Linux 在 x86 上最多可以管理 64GiB 的交換。)您可以在Mel Gorman 的了解 Linux 虛擬記憶體管理器的“交換管理”一章中找到對所有這些的更詳細的描述。