1. 程式人生 > >讀懂作業系統之虛擬記憶體(一)

讀懂作業系統之虛擬記憶體(一)

前言

由於個人對虛擬記憶體這塊特別感興趣,所以就直接暫且跳過其他,接下來將通過幾篇文章進行詳細講解,當然其他基礎內容後續在我進行相應整體學習後也會同步輸出文章,比如作業系統概念、程式連結、程序管理、頁面置換演算法、流水線、浮點指令、記憶體管理、磁碟管理等內容。不管周遭的環境如何,畢竟還很菜,堅持每天讓自己進步一點點,放下暫時的焦慮,不如專注於眼前的學習,跟著我一起學習作業系統吧。

虛擬儲存器設計初衷

快取從高到低,主存可作為磁碟的快取,我們將這項技術稱作為虛擬儲存器,基於歷史觀點,構造虛擬儲存器的主要出於兩個目的,其一是允許雲端計算在多個虛擬機器之間有效而安全的共享儲存器,其二則是受限的主存容量對程式設計所造成的極大影響。有了虛擬儲存器這樣可確保每個程式只能對劃分給它的那部分主存進行讀寫操作,而主存只需存放程式中的活躍區域。虛擬儲存器實現程式地址空間到實體地址的轉換,通過這種轉換處理加強了各個程式地址之間的保護。若使用者載入多個程式直接到主存,很顯然最終可能會超過主存的容量,如此一來,將程式進行解除安裝或轉入成為程式設計師不可推卸的責任,加重了程式設計師的負擔,那麼怎樣才能將程式設計師從這種情況中解放出來呢?現代作業系統將主存提供了一種對主存的抽象概念,叫作虛擬記憶體,虛擬記憶體是硬體異常,硬體地址翻譯、主存、磁碟檔案和核心軟體的完美互動,虛擬記憶體主要提供了三種能力:【1】將主存看成是一個儲存在磁碟上的地址空間的快取記憶體(作為快取)【2】為每個程序提供一致的地址空間,從而簡化記憶體管理(作為記憶體管理)【3】防止每個程序的地址空間被其他程序所破壞(作為記憶體保護)。

對映原理:CPU生成一個虛擬地址(Virtual Address簡稱VA)來訪問主存,但是在此之前需要將虛擬地址轉換為實體地址,這個過程稱作為地址轉換或地址對映或地址翻譯,為進行此操作需要CPU硬體和作業系統合作,通過記憶體管理單元(Memory Management Unit)上的地址翻譯硬體,利用儲存在主存上的查詢表來翻譯虛擬地址,該表的內容由作業系統管理。

頁表地址翻譯

虛擬記憶體系統將虛擬記憶體劃分為固定大小的塊,這個塊我們稱作為虛擬頁(Virtual Page簡稱VP),同理將實體記憶體劃分為物理頁(Physical Page簡稱PP),也叫頁幀(Page Frame)。這裡我們需要明白虛擬地址、虛擬頁、實體地址、物理頁這四者之間的聯絡。如下圖,通過CPU產生虛擬地址訪問主存的實體地址,而虛擬儲存器和物理儲存器分別被劃分成虛擬頁和物理頁,所以結果變成將虛擬頁對映到物理頁。

 

在虛擬儲存器中,地址被劃分為虛頁號(Virtual Page Number簡稱VPN)和虛擬頁頁偏移(Virtual Page Offset簡稱VPO),如下為從虛擬頁到物理頁號(Physical Page Number簡稱PPN)的轉換。物理頁構成實體地址的高位部分,而頁偏移保持不變,構成實體地址的低位部分。頁偏移的位數決定了頁的大小,當然,虛擬頁地址可定址的頁數與實體地址可定址的頁數可以不同。

例如具有32位邏輯地址的作業系統,如果每個頁面的大小為4KB,由於上述物理頁號有18位,那麼儲存器物理頁數為2^18,因此,邏輯上最多可以支援1GB的主存,但是實際上虛擬地址空間可支援4GB,如此為解決主存的受限控制。和快取機制一樣,我們必須有某種機制來判斷一個虛擬頁是否快取在DRAM中某一個地方,如果是,那麼系統必須確定這個虛擬頁存放在哪個物理頁中,如果未命中,系統必須確定這個虛擬頁儲存在磁碟的哪個位置,然後在實體記憶體中選擇一個犧牲頁,並將虛擬頁從磁碟複製到DRAM中,然後替換這個犧牲頁。此功能由軟硬體共同提供,包括作業系統軟體、MMU中的地址翻譯硬體、存放在實體記憶體中的頁表(Page Table簡稱PT)所決定,上述將虛擬頁對映到物理頁就是通過查詢頁表實現,一個頁表是由頁表條目(Page Table Entry簡稱PTE)的陣列組成。如下為頁表簡要資訊版本:

我們看到上述每個PTE是由一個有效位和一個包含物理頁號或磁碟地址組成,有效位標識虛擬頁是否被快取在主存中, 若為1則說明該虛擬頁已被快取在主存中,若為0分為兩種情況,可能是虛擬記憶體未建立虛擬頁,也有可能是已建立虛擬頁但還未快取到主存,所以虛擬頁集合由3個子集組成:【1】虛擬記憶體系統還未分配或未建立、【2】已快取在實體記憶體中的已分配頁、【3】未快取在實體記憶體中的已分配頁。頁表在主存中的位置由硬體決定,硬體包含一個指向頁表首地址的頁表基址暫存器(Page Table Base Register簡稱PTBR)。簡要翻譯過程如下圖所示

我們進一步得出MMU將虛擬地址對映為實體地址的詳細過程:CPU產生虛擬地址,然後從虛擬地址中得到虛擬頁號,接下來通過將虛擬頁號作為索引去查詢頁表,通過得到對應PTE上的有效位來判斷當前虛擬頁是否在主存中,若命中則將對應PTE上的物理頁號和虛擬地址中的虛擬頁偏移進行串聯從而構造出主存中的實體地址,否則未命中(專業名詞稱為“缺頁”),此時MMU將引發缺頁異常,從CPU傳遞到作業系統核心處理缺頁異常處理程式,此時將選擇一個犧牲頁並將對應所缺虛擬頁調入並更新頁表上的PTE,缺頁處理程式再次返回到原來的程序,再次執行缺頁指令,CPU重新將虛擬地址發給MMU,此時虛擬頁已存在實體記憶體中,所以命中,最終將請求的字返回給處理器。詳細過程如下:

程序的地址空間以及它在主存中可以訪問的所有資料,都由駐存在主存中的頁表所定義,作業系統只是簡單的載入頁表暫存器用來指向它所想啟用的程序頁表,而不是儲存整個頁表。由於不同程序使用相同的虛擬地址,因此每個程序有各自的頁表,作業系統負責分配物理主存和更新頁表,因為我們通過將頁表分離來保護程序,進而保證不同程序的虛擬地址空間不會發生任何衝突。上述我們已經得知,一個32位邏輯地址空間的系統,每個頁面的大小為4KB(2^12),那麼頁表將包含(2^32/2^12)= 大約100萬個頁表條目即PTE,假設每個條目佔4個位元組,那麼每個程序的頁表將佔用(4*(2^32/2^12))= 4MB的記憶體。

TLB加快地址翻譯

我們知道每次CPU產生一個虛擬地址就必須通過MMU去查詢頁表從而得到PTE,但是頁表儲存在主存中,因此程式訪存至少需要兩次:第一次訪存獲取實體地址、第二次訪存獲得資料。提高訪問效能的關鍵在於依靠頁表的訪問區域性性,當一個轉換的虛擬頁號被使用時,它可能在不久的將來會被再次用到,因為對該頁中字的引用同時具有時間區域性性和空間區域性性。為了消除這樣的開銷,在MMU中包括一個關於PTE的小的快取,稱為翻譯後備緩衝器(Translation-Lookasice Buffer簡稱TLB),有些書中被稱為快表,所以TLB存在的目的是:用於記錄最近使用地址的對映資訊的快取記憶體,從而可以避免每次都訪問頁表。TLB是一個小的、虛擬定址的快取,其中每一行都儲存著一個由單個PTE組成的塊,TLB大概包含64-1024個PTE。如下圖所示

從虛擬頁號中提取出用於組選擇和行匹配的索引和標記欄位,如果TLB有 T= 2^t個組,那麼TLB索引(TLBI)是由VPN的t個最低位組成,而TLB標記(TLBT)是由VPN中剩餘的位組成。上述我們瞭解到虛擬地址由虛擬頁號和虛擬頁偏移量組成,在這裡再進行補充,虛擬地址由虛擬頁號(VPN)、虛擬頁偏移量(VPO)、TLBI(TLB索引)、TLBT(TLB標記)組成,對於實體地址由物理頁號(PPN)、物理頁偏移量(PPO)、緩衝塊內的位元組偏移量(CO)、快取記憶體索引(CI)、快取記憶體標記(CT)組成。那麼利用TLB加快地址翻譯的整個大概過程是怎樣的呢?CPU產生一個虛擬地址,MMU從虛擬地址中提取出虛擬頁號,然後從TLB中根據虛擬頁號取出相應的PTE,進而通過物理頁號和虛擬頁偏移構造出實體地址,將其傳送到快取記憶體/主存,快取記憶體/主存將返回的資料返回給CPU(現代作業系統都已有SRAM的快取記憶體(一級快取、二級快取、三級快取),因為地址翻譯硬體發生在訪問快取記憶體之前,所以我們到底是通過虛擬地址還是實體地址訪問快取記憶體呢?大多數都是選擇實體地址訪問快取記憶體)。整個過程如下圖:

總結

本節屬於小試牛刀,只是從整體上去分析虛擬記憶體地址翻譯原理,裡面仍涉及太多細節,比如頁面交換策略、頁表和TLB所包含詳細內容,多級頁表、TLB查詢PTE、TLB缺失等,下一節我們分析TLB缺失和頁面交換具體原理。&n