Exynos4412 内核移植(四)—— MMU 相关知识解析
一、MMU的產生
? ? ? 許多年以前,當人們還在使用DOS或是更古老的操作系統的時候,計算機的內存還非常小,一般都是以K為單位進行計算,相應的,當時的程序規模也不大,所以內存容量雖然小,但還是可以容納當時的程序。但隨著圖形界面的興起還用用戶需求的不斷增大,應用程序的規模也隨之膨脹起來,終于一個難題出現在程序員的面前,那就是應用程序太大以至于內存容納不下該程序,通常解決的辦法是把程序分割成許多稱為覆蓋塊(overlay)的片段。覆蓋塊0首先運行,結束時他將調用另一個覆蓋塊。雖然覆蓋塊的交換是由OS完成的,但是必須先由程序員把程序先進行分割,這是一個費時費力的工作,而且相當枯燥。人們必須找到更好的辦法從根本上解決這個問題。不久人們找到了一個辦法,這就是 虛擬存儲器(virtual memory) .虛擬存儲器的基本思想是程序,數據,堆棧的總的大小可以超過物理存儲器的大小,操作系統把當前使用的部分保留在內存中,而把其他未被使用的部分保存在磁盤上比如對一個16MB的程序和一個內存只有4MB的機器,OS通過選擇,可以決定各個時刻將哪4M的內容保留在內存中,并在需要時在內存和磁盤間交換程序片段,這樣就可以把這個16M的程序運行在一個只具有4M內存機器上了。而這個16M的程序在運行前不必由程序員進行分割。? ? ? 任何時候,計算機上都存在一個程序能夠產生的地址集合,我們稱之為 地址范圍 。這個范圍的大小由CPU的位數決定,例如一個32位的CPU,它的地址范圍是0~0xFFFFFFFF (4G)而對于一個64位的CPU,它的地址范圍為0~0xFFFFFFFFFFFFFFFF (64T),這個范圍就是我們的程序能夠產生的地址范圍,我們把這個地址范圍稱為 虛擬地址空間 ,該空間中的某一個地址我們稱之為 虛擬地址 。與虛擬地址空間和虛擬地址相對應的則是 物理地址空間和物理地址 ,大多數時候我們的系統所具備的物理地址空間只是虛擬地址空間的一個子集,這里舉一個最簡單的例子直觀地說明這兩者,對于一臺內存為256MB的32bit x86主機來說,它的虛擬地址空間范圍是0~0xFFFFFFFF(4G),而物理地址空間范圍是0x000000000~0x0FFFFFFF(256MB)。
? ? ?在沒有使用虛擬存儲器的機器上,虛擬地址被直接送到內存總線上,使具有相同地址的物理存儲器被讀寫。而在使用了虛擬存儲器的情況下,虛擬地址不是被直接送到內存地址總線上,而是送到內存管理單元—— MMU (主角終于出現了)。他由一個或一組芯片組成,一般存在與協處理器中,其功能是 把虛擬地址映射為物理地址 。
?
二、MMU工作過程
? ? ? 大多數使用虛擬存儲器的系統都使用一種稱為分頁(paging)。虛擬地址空間劃分成稱為頁(page)的單位,而相應的物理地址空間也被進行劃分,單位是頁框(frame).頁和頁框的大小必須相同。接下來配合圖片我以一個例子說明頁與頁框之間在MMU的調度下是如何進行映射的:
? ? ? ?這里提到了一個概念,就是 頁表,下面將詳細介紹?頁表。
三、頁表
? ? ? ? ?首先讓我們來介紹一個概念-頁表(page table)。頁表就是存儲在內存中的一張表,表中記錄了將虛擬地址轉換成物理地址的關鍵信息。MMU正是通過對頁表進行查詢,實現了地址之間的轉換。也就是說,MMU每次工作的時候都要去查這張表,從中找出與虛擬地址相對應的物理地址,然后再進行數據存取。頁表的作用如下圖所示。
? ? ? ?頁表中的條目被稱為頁表項(page table entry),一個頁表項負責記錄一段虛擬地址到物理地址的映射關系,稍后我們會詳細介紹。
? ? ? ?既然頁表是存儲在內存中的,那么程序每次完成一次內存讀取時都至少會訪問內存兩次,相比于不使用MMU時的一次內存訪問,效率被大大降低了,如果所使用的內存的性能比較差的話,這種效率的降低將會更明顯。因此,如何在發揮MMU優勢的同時使系統消耗盡量減小,就成為了一個亟待解決的問題。
? ? ?于是,TLB產生了。TLB是什么呢?我們叫它轉換旁路緩沖器,它實際上是MMU中臨時存放轉換數據的一組重定位寄存器。既然TLB本質上是一組寄存器,那么不難理解,相比于訪問內存中的頁表,訪問TLB的速度要快很多。因此如果頁表的內容全部存放于TLB中,就可以解決訪問效率的問題了。
? ? ? ? ?然而,由于制造成本等諸多限制,所有頁表都存儲在TLB中幾乎是不可能的。這樣一來,我們只能通過在有限容量的TLB中存儲一部分最常用的頁表,從而在一定程度上提高MMU的工作效率。
? ? ? ? 這一方法能夠產生效果的理論依據叫做存儲器訪問的局部性原理。它的意思是說,程序在執行過程中訪問與當前位置臨近的代碼的概率更高一些。因此,從理論上我們可以說,TLB中存儲了當前時間段需要使用的大多數頁表項,所以可以在很大程度上提高MMU的運行效率。
? ? ? ?讓我們接著聊頁表。頁表是由頁表項組成的,每一個頁表項都能夠將一段虛擬地址空間映射到一段物理地址空間中。這里所謂的這段虛擬地址空間,更專業地講,應該叫頁,一個頁對應了頁表中的一項,頁的大小通常是可選的。在ARM中,一個頁可以被配置成1K、4K、64K或1M大小(ARM v6體系以后,不再支持1K大小的頁),分別叫做微頁、小頁、大頁和段頁。頁的大小決定了映射的粒度,是根據實際應用有選擇地配置的。以1M為例,按照我們前面的描述,假設系統中將有64M內存需要被映射,那么我們一共需要64M/1M個頁表項,而每個頁表項需要占據4個字節,也就是說,有256字節的內存要專門負責地址映射,不能用于其他用途。
? ? ? ?對于1K、4K和64K大小的頁,MMU采用二級查表的方法,即首先由虛擬地址索引出第一張表的某一段內容,然后再根據這段內容搜索第二張表,最后才能確定物理地址。這里的第一張表,我們叫它一級頁表,第二張表被稱為是二級頁表。采用二級查表法的主要目的是減小頁表自身占據的內存空間,但缺點是進一步降低了內存的尋址效率。不同大小的頁對查表方法的支持程度如表3-1所示。
表3-1 ?不同大小頁的查表方法
| ? | 頁大小 | |||
| 查表方法 | 1K | 4K | 64K | 1M |
| 一級查表 | 不支持 | 不支持 | 不支持 | 支持 |
| 二級查表 | 支持 | 支持 | 支持 | 不支持 |
下面,首先來研究一下相對簡單的一級查表。
1、一級查表
? ? ? ?一級查表只支持大小為1M的頁。準確地講,這里所謂的1M大小的頁,應稱為段(section)。此時,一級頁表也被稱為段頁表。圖3-4描述了段頁表的內存分布情況和段頁表項的具體格式。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖3-4??段頁表項的結構
? ? ? ? ? 段頁表中的每一項都類似于上圖中的形式,其中:
? ? ? (1)31~20位段表示物理地址的基地址,一共12位,也就是說,如果我們通過虛擬地址找到某一個段頁表項,那么就可以確定這段虛擬地址所對應的物理地址的高12位了。因為段頁表項后20位正好可以描述1M的內存,因此基地址每增加一個單位,物理地址就會增加1M空間。所以,我們也可以說該基地址表示了虛擬地址屬于哪1M范圍的物理地址。由此可知,使用段頁表進行地址映射時,每一頁能夠描述1M的物理地址空間。進一步講,段頁表最多支持1024個頁,最多占用系統4K字節的內存來存放頁表。
? ? ? (2)11~10位是AP位,區分了用戶模式和特權模式對同一個頁的不同訪問權限。例如,當AP位為"11"時,表示任何模式下都可以對該空間進行讀寫,"10"則表示特權模式可讀寫該頁,而用戶模式只能讀取該頁。對AP位詳細的描述請參考頁權限一節。
? ? ? (3)8~5位代表該頁所屬的域。在ARM體系結構中,系統中規定了16個域,因此使用4個位就能表示該頁屬于哪個域,而每一個域又有各自獨立的訪問權限,從而實現了初級的存儲器保護。
? ? ? (4)3位和2位分別代表cache和write buffer。相應的位為1則表示被映射的物理地址將使用cache或write buffer。關于cache和write buffer的有關內容,我們稍后會詳述。
? ? ? (5)1~0位。這兩位用來區分頁表類型,對于段頁表,這兩位的值總是為"10"。
? ? ? ? 總的來說,段頁表項的內容雖然復雜,但歸結起來無非就是兩個問題,一是,如何解決某一虛擬地址屬于哪段物理地址,二是,如何確定這段地址的訪問權限。使用其他形式的頁表,本質上也是要解決這兩個問題。
? ? ?
? ? ? ?現在,假設段頁表已經被成功地添加到內存之中了,那么接下來的問題是我們應該怎樣通過一個虛擬地址找到與之對應的段頁表項呢?找到頁表項之后,又是怎樣找到對應的物理地址的呢?
? ? ? 很顯然,虛擬地址本身就可以解決上述問題。
? ? ? 如下圖所示,首先,我們要讓MMU知道段頁表在內存中的首地址,也就是圖中所說的頁表基地址,因為段頁表是我們通過程序確定的,存儲在什么位置程序員自然清楚。然后,在CPU需要尋址的時候,MMU就可以自動地利用頁表將虛擬地址映射為物理地址并尋址物理地址,其步驟如下:
? ? (1)MMU取出虛擬地址的前12位作為頁表項的偏移,結合頁表基地址,找到對應的頁表項。具體來說,就是將這12位數取出,然后左移兩位和頁表基地址相或,就能得到相應頁表項的地址了。例如,頁表基地址是0x10000000,如果虛擬地址是0x00101000,則前12位數是0x001,那么根據上述步驟將其左移兩位,結果為0x004,那么頁表項地址就應該是0x10000000|0x004=0x10000004,從該地址中讀取的32位的數據即是該虛擬地址所對應的頁表項。
? ? ?(2)找到與虛擬地址對應的頁表項之后,就可以從該頁表項中讀出一個重要信息,如圖3-4所示,頁表項的前12位定位了該虛擬地址所對應的物理地址在哪個范圍內。例如,從0x10000004中讀出的頁表項的內容為0x30000c12,那么我們就已經知道了,虛擬地址0x00101000對應的物理地址在0x30000000與0x30100000之間。既然地址范圍已經清楚了,那么虛擬地址又該定位到該范圍的哪個位置呢?這就要靠虛擬地址的后20位了。
圖3-5??段頁表映射過程
? ? ? ? 3)MMU將虛擬地址后20位和頁表項內容清除掉后20位之后的結果做與的操作,就得到了與虛擬地址對應的實際物理地址了。例如,頁表項的內容為0x30000c12,清除掉后20位的結果為0x30000000,虛擬地址的后20位為0x01000,將其和0x30000000相與,結果為0x30001000,這便是最終的物理地址。
? ? ? 當然,MMU在進行地址映射期間,還要進行訪問權限的檢查,方法是讀出頁表項的權限位,按照既定規則去檢查,如果允許對該地址進行訪問則正常訪問,如果不允許訪問,則拋出異常,通過程序將其捕獲并處理。這便是使用段頁表時MMU的地址映射過程。
示例:viraddr是0xc000?0000?映射到?phyaddr?0x2000?000
2、二級頁表:
? ? ? ?可以讓我們訪問的內存不是連續的
? ? ? ?我們也可以選擇使用二級查表的方式去實現地址映射。從原理上講,一級查表和二級查表其實并沒有太大的差別。使用二級查表法,經過一級頁表得到的數據不再是記錄了物理地址信息的數據了,而是二級頁表項的索引信息。而這些信息除了相應位和標志與一級頁表項略有不同之外,與一級查表并無不同。
線性地址高10位---------索引頁目錄表----------->找到相應頁表
線性地址中間10位---------索引頁表----------->得到頁表中相應的項,其中的高20位就是物理地址的高20位
線性地址低12位-------------------->物理地址的低12位
總結
以上是生活随笔為你收集整理的Exynos4412 内核移植(四)—— MMU 相关知识解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 软件开发中协议制定的注意事项
- 下一篇: Orchard之生成新模板