內存管理之8:情景分析之堆棧擴展

date: 2014-09-27 19:09app

注:本文展現的代碼來自2.4.0版本的內核,入口函數do_page_fault定義在<arch/mm/fault.c>中。函數

整體處理流程:指針

情景分析之堆棧擴展

備註:code

  • do_page_fault前半部分流程請參考「越界訪問」的情景分析。
  • 虛存區間結構vm_area中包含一個vm_operations_struct類型的指針vm_ops。vm_operations_struct定義了一組函數指針,其中的nopage函數指針指定了當該區間發生了頁面異常時應該執行的操做,詳情請參考《虛存管理中的抽象》。做爲堆棧區間的vma,跟文件系統或頁面共享沒有關係,於是沒有指定nopage函數,內核將調用do_anonymous_page函數。
  • 「讀操做觸發的頁面異常」,開始時都一概映射到同一個物理內存頁面empty_zero_page上,而無論其虛擬地址是什麼。empty_zero_page的定義以下:
<include/asm/Pgtable.h>
        /*
         * ZERO_PAGE is a global shared page that is always zero: used
         * for zero-mapped memory areas etc..
         */
        extern unsigned long empty_zero_page[1024];
        #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))

  可見這個頁面的內容全爲0,也就是說,在映射之初去讀的話讀出的值全爲0。這是能夠理解的:你去讀一個「還沒有創建映射」的地址,這個地址對用戶空間來講,就像是一塊新的未開墾(未進行寫操做)的土地,讀出的結果爲0是理所應當的。若是後續要對該地址進行寫操做,那麼內核將會爲該虛擬地址從新映射到一塊新的的物理頁面上。這就是內核中的COW(Copy On Write)技術,在《進程調度與切換》章節中咱們還會看到。blog

  • 整個堆棧擴展的過程能夠總結爲:分配新的物理頁面,經過設置頁面表將虛擬地址映射到物理頁面上。
  • 異常返回到用戶空間後,將從新執行因異常而「夭折」的指令,對於該場景就是從新執行「子函數返回地址入棧」的指令,而後再繼續往下執行,這點與中斷不一樣。中斷髮生時,CPU會將下一條指令也就是接下來本該執行的指令的地址壓入堆棧,做爲中斷服務的返回地址;而異常發生時,CPU將因異常沒法完成的指令(也就是觸發異常的指令)自己的地址壓入堆棧,做爲異常服務程序的返回地址,這樣從異常服務返回時,就能夠「從頭再來」完成未竟的事業。這種差別性(返回地址的差別),是CPU內部的硬件電路實現的,不須要軟件的干預。
相關文章
相關標籤/搜索