ARM-Linux (臨時,正式) 建立頁表的比較【轉】


 

很久沒有寫博客了,由於之前的寫關於OMAP3530文章還沒有整理。再加上一直在找工作,找到工作后又投入到另外的平台去工作。始終在忙忙碌碌,但是對於代碼確實漸漸疏遠。

在做項目的時候要使用DDR3分配內存,不經意間使用要和MMU以及TLB打交道。因此特地寫下這篇文章以備后用。(工作就是在和遺忘作斗爭)!

 

Linux在啟動之初會建立臨時頁表,但是在start_kerne函數中setup_arch又會建立正真的頁表和頁目錄。那么兩套方案是如何過渡的?假如在MMU開啟的時候把之前的臨時頁表給覆蓋了或者修改了,會不會影響后續的啟動過程?帶着這些問題分析一下。

 


首先來看一下基於ARM的頁表管理和MMU的行為分析:

 

Arm上的linux(正式)頁表采用的是一級粗頁表結合二級小頁表實現4G空間的訪問。如上圖說明。

 

一級表 (1024 Entrys)

 

二級表 (1024 Entrys)

 

虛擬地址后12位Offset尋址空間是4096B 4k的空間

 

Arm上的linux(臨時)頁表采用的是段式頁表,每一個entry可以映射1M的空間,結合后面的20bits位(尋址空間正好是1M)

 

一級表 (4096 Entrys)

 

虛擬地址的后20位offset尋址空間是1M


接着來看一下linux如何建立頁表的過程。

 

Head.S中有一段使用匯編編寫的初始化代碼。Mmu.c中有一段使用c語言寫的建立頁表的代碼。C語言的代碼很經典,可能匯編更經典。這里不多分析了。可以百度文章很多分析。

 

關鍵問題在於一個變量swap_pgdir

 

1..macro    pgtbl, rd  

 

2.  

 

3.       ldr   \rd, =(KERNEL_RAM_PADDR - 0x4000)  

 

4.  

 

5..endm  

 

KERNEL_RAM_PADDR = 0 x XXXXXXXX這是內存的物理地址,那么頁表的建立也在這物理地址相關的區域內。

 

臨時頁表使用的是段式映射,也稱之為平坦映射。那么4G的空間划分為1M為單位的訪問單元,需要4096個Entrys。應為Arm采用32位的數據線,因此每一個Entry占用一個32位的區段,也就是4B。

 

正式頁表建立的過程分為二級映射也尋找index的過程。每次把線性地址划分為兩段,每一段都作為索引根據TLB BASE的便宜尋找下一級的索引項。最后結合虛擬地址的最后偏移(10 bit)作為依據在4K的空間內尋址。

 

 

問題來了,這兩種映射會不會應為后一種映射的建立把之前的映射破壞掉,導致linux一個復雜的尋址系統無法正常工作呢?答案肯定不會。

 

圖示比文字描述來的直接,還是直接上兩張圖說明問題:

 

由上圖可知:臨時頁表建立的空間和正式頁表建立的空間分別部署於不同的空間,因此不會出現覆蓋或者修改等現象。同時一二級頁表項目錄中的內容頁值得研究。最后兩位同時表現出來的控制邏輯,讓MMU翻譯地址的過程中有章可循。結合MMU中的AP位規定了訪問空間的屬性,是否可以訪問拒絕訪問等。

 

    最后希望圖示可以幫助讀者理解映射的意圖。文中難免有些地方會引起歧義或者不足之初,希望linux大俠指正點評。


免責聲明!

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



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