1. 程式人生 > >編譯後的程式是如何在作業系統(linux)中執行的,虛擬地址空間到實際實體記憶體的訪問

編譯後的程式是如何在作業系統(linux)中執行的,虛擬地址空間到實際實體記憶體的訪問

Linux中,每個程序通過一個task_struct結構體描述,每個程序地址虛擬空間通過一個mm_struct描述,c語言中每個段空間通過vm_area_struct描述,關係如下,

當執行一個程式時,linux建立一個程序,通過sys_exec()將該程式的內容(程式編譯後產生的是虛擬地址空間對映到程序的虛擬地址空間中而不是實體記憶體中,生成一組vm_area_struct資料結構用來表示可執行程式的資訊。具體步驟如下:

(1)建立一組vm_area_struct

(2)將程式編譯的起始地址儲存到vm_startvm_end

(3)將磁碟file控制代碼儲存在vm_file

中;

(4)將對應段在磁碟file中的偏移值儲存在vm_pgoff中;

(5)將操作該磁碟file的磁碟操作函式儲存在vm_ops中;

(6)假設程式有一條指令需要讀取地址vm_start~vm_end之間的某內容,例如:

mov[0x08000011],%eax; 那麼將會執行如下序列:

(1)cpu依據CR3(current->pgd)找到0x08000011地址對應的pgd[i],由於該pgd[i]內容保持初始化狀態即為0,導致cpu page fault

(2)呼叫do_page_fault()系統呼叫,為pgd[i]在記憶體中分配一個頁表,並該讓頁表指向它,如下圖所示:

(3)pte[j]

分配一個真正的實體記憶體頁面,依據vm_area_struct中的vm_filevm_pgoffvm_ops,呼叫filemap_nopage將磁碟filevm_pgoff偏移處的內容讀入到該物理頁面中,如下圖:

1 分配實體記憶體頁

2 從磁碟檔案中將內容讀取到實體記憶體頁面中

總結,執行程式過程中,如果當前指令或資料在虛擬地址空間中,實際沒有在實體記憶體中,將發生缺頁錯誤,這時作業系統再從實體記憶體分配一個空閒的物理頁,並將虛擬地址頁對應的資料從磁碟載入到該物理頁中,並建立頁表項和頁幀的對映關係。假設程式佔用記憶體非常大,隨著程序的執行,缺頁錯誤不斷產生,作業系統會響應每個缺頁錯誤並未程序分配實體記憶體頁框。但是實體記憶體是有限的,全部實體記憶體都分配給程序後,如果程序繼續丟擲缺頁錯誤,此時作業系統就會採用

頁置換演算法,在保證程序正常執行的前提下,將先前的分配給程序的物理頁收回,重新分配給程序。常用的頁面置換演算法有先進先出FIFO),最近未使用NRU),最近最少使用LRU)等。