頁表


  雖然應用程序操作的對象是映射到物理內存之上的虛擬內存,但是處理器直接操作的卻是物理內存。所以當應用程序訪問一個虛擬地址時,首先必須將虛擬地址轉換為物理地址,然后處理器才能解析地址訪問請求。地址的轉換工作需要通過查詢頁表才能完成,概括地講,地址轉換需要將虛擬地址分段,使每段虛擬地址都作為一個索引指向頁表,而頁表項則指向下一級別的頁表或者指向最終的物理頁面。

  Linux中使用三級頁表完成地址轉換。利用多級頁表能夠節約地址轉換需占用的存放空間。如果利用三級頁表轉換地址,即使是64位機器,占用的空間也很有限。但是如果使用靜態數組實現頁表,那么即便是在32位機器上,該數組也將占用巨大的存放空間。Linux對所有體系結構,包括那些不支持三級頁表的體系結構(比如,有些體系結構只使用兩級頁表或者使用散列表完成地址轉換)都使用三級頁表管理,因為使用三級頁表可以利用“最大公約數”的思想——一種設計簡單的體系結構,可以按照需要在編譯時簡化使用頁表的三級結構,比如只使用兩級。

  頂級頁表是頁全局目錄(PGD),它包含一個pgd_t類型數組,多數體系結構中pgd_t類型等同於無符號長整型類型。PGD中的表項指向二級頁目錄中的表項PMD。

  二級頁表是中間頁目錄(PMD),它是一個pmd_t類型數組,其中的表項指向PTE中的表項。

  最后一級的頁表簡稱頁表,其中包含了pte_t類型的頁表項,該頁表項指向物理頁面。

  多數體系結構中,搜索頁表的工作由硬件完成(至少某種程度上)。雖然通常操作中,很多使用頁表的工作都可以由硬件執行,但是只有在內核正確設置頁表的前提下,硬件才能方便的操作它們。下圖描述了虛擬地址通過頁表找到物理地址的過程。

 

 

  由於每次對虛擬內存中頁面的訪問都必須先解析它,從而得到物理內存中對應的地址,所以頁面操作的性能非常關鍵。但不幸的是,搜索內存中的物理地址速度很有限,因此為了加快搜索,多數體系結構都實現了一個翻譯后緩沖器(translate lookaside buffer,TLB)。TLB作為一個將虛擬地址映射到物理地址的硬件緩存,當請求訪問一個虛擬地址時,處理器將首先檢查TLB中是否緩存了該虛擬地址到物理地址的映射,如果在緩存中直接命中,物理地址將立刻返回;否則,就需要再通過頁表搜索需要的物理地址。

  雖然硬件完成了有關頁表的部分工作,但是頁表的管理仍然是內核的關鍵部分——而且在不斷地改進。2.6版內核對頁表管理的主要改進是:從高端內存分配部分頁表。今后可能的改進包括通過在寫時拷貝(copy-on-write)的方式共享頁表。這種機制使得在fork()操作中可由父子進程共享頁表。因為只有當子進程或父進程試圖修改特定頁表項時,內核才去創建該頁表項的新拷貝,此后父子進程不再共享該頁表項。可以看到,利用頁表項可以消除fork()操作中頁表拷貝所帶來的消耗。

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM