MMU探索之旅
現在有很多關于MMU的講解材料,大都比較晦澀難懂,參考了一些相關材料后,在這里用簡明易懂的語言整理一下,以備后用。
???????在講解MMU之前,先看看我們需要對MMU了解哪些方面:
???? (1)MMU的產生
???? (2)MMU的概述
???? (3)MMU的功能和原理
???? (4)MMU使用的相關軟硬件支持
??? 這里只是對MMU做一個較為概括的講述,內部的具體實現得參考相關書籍。
(1)MMU的產生
??? 大家都知道,以前的計算機的內存都很小,基本上都是KB級別的,之所以在這么小的內存中跑程序,是因為以前的應用程序都是文本界面的,程序本身也比較小。但是,后來程序日趨圖形化,而且應用軟件也被做的越來越多大,小內存的瓶頸越顯突出,雖然曾有過一些辦法來緩解這種局面,但是這根本解決不了問題,而且費時費力。
??? 不久人們找到了一個辦法,這就是虛擬存儲器(virtual memory)技術,虛擬存儲器的基本思想是程序,數據,堆棧的總的大小可以超過物理存儲器(物理內存)的大小,操作系統把當前使用的部分保留在內存中,而把其他未被使用的部分保存在磁盤上,這樣對于用戶而言,真的好像在很大的內存中跑程序一樣。
(2)MMU的概述
??? 在介紹MMU概念之前,先來了解一下地址范圍,虛擬空間,虛擬地址,物理空間,物理地址,分頁機制等概念。
??? 地址范圍:計算機上的一個程序(或者說處理器)能夠產生的地址集合,我們稱之為地址范圍。這個范圍的大小隨著計算機的體系結構的不同而不同,即由CPU的位數決定,例如一個32位的CPU,它的地址范圍是0~0xFFFFFFFF (4G),這是目前pc機上最常用的地址范圍。而對于一個64位的CPU,它的地址范圍為0~0xFFFFFFFFFFFFFFFF (64T).這個范圍就是我們的程序能夠產生的地址范圍,本質上,地址范圍是由系統地址總線的數量決定的,即如果你的機器上有n根地址總線,就有2的n次方的地址范圍。
??? 虛擬空間和虛擬地址:我們把地址范圍稱為虛擬地址空間,該空間中的某一個地址我們稱之為虛擬地址。
??? 物理空間和物理地址:與虛擬地址空間和虛擬地址相對應的則是物理地址空間和物理地址,大多數時候我們的系統所具備的物理地址空間只是虛擬地址空間的一個子集。這里舉一個最簡單的例子直觀地說明這兩者,對于一臺內存為256M的32bit x86主機來說,它的虛擬地址空間范圍是0~0xFFFFFFFF(4G),而物理地址空間范圍是0x000000000~0x0FFFFFFF(256M)。
??? 分頁機制:大多數使用虛擬存儲器的系統都使用一種稱為分頁(paging)機制,在不同的機器上頁的大小不同,一般是4KB,(在后面的敘述中的頁也是指4KB),虛擬地址空間劃分成稱為頁(page)的單位,而相應的物理地址空間也被進行劃分,單位是頁楨(frame)頁和頁楨的大小必須相同,這樣就可以把物理空間和虛擬空間進行準確的映射了,這在后面會詳細介紹。
??????? MMU:在沒有使用虛擬存儲器的機器上,虛擬地址被直接送到內存總線上,使具有相同地址的物理存儲器被讀寫;而在使用了虛擬存儲器的情況下,虛擬地址不是被直接送到內存地址總線上,而是送到存儲器管理單元MMU,把虛擬地址映射為物理地址,然后將映射后的物理地址送到內存的地址總線上。
?
(3)MMU的功能和原理
??? 因為我是學ARM的,所以在這里以ARM系統為例,MMU主要完成以下工作:
???????<1>?虛擬存儲空間到物理存儲空間的映射,實現從虛擬地址到物理地址的轉換
???????<2>?存儲器訪問權限的控制
???????<3>?設置虛擬存儲空間的緩沖特性
???????老規矩,在介紹MMU的功能和原理之前,先來了解一下幾個名詞:
???????1?傳輸表:這是一種頁表,用來保存虛擬地址到物理地址的映射信息。既然是頁表,就是說這里有4K(4096)個表項,每個表項占4個字節,所以傳輸表的大小為16KB。
???????2 TLB:Translation Lookaside Buffer,這是一個小容量的Cache,稱為塊表,是用來提高虛擬地址到物理地址映射的速度的,后面會詳細介紹。
???????3 CP15:ARM總共有16個協處理器,這是最后一個協處理器,也是最總要的一個(個人看法,因為系統底層的程序員總要跟它打交道),用來協調ARM處理器工作的,相信你能從名字上看得出來。
???????4 c0, c1, ……, c15:這些寄存器每個協處理器都有,名字一樣但對應的物理寄存器卻不同,用來控制協調協處理器工作的,包括對MMU操作的影響。
???????5 MPU:這是內存保護單元,不用多說,是用來保護內存不被非法破壞的,它和MMU相得益彰,這里不對MPU多做解釋。
?
<1>?虛擬存儲空間到物理存儲空間的映射
???????這里從處理器訪問內存過程來說明MMU的工作原理,為了便于理解我們由簡入深講解,然后總結訪問內存的詳細流程:
???????當處理器產生一個內存訪問請求時,將傳輸一個虛擬地址給MMU(如果機器沒有MMU功能或禁止了MMU功能就另當別論),那么它會轉入保存在內存中的傳輸主表(在下面我將用段表來代替),來獲取所有訪問地址的物理地址和訪問權限,這里假設虛擬內存映射采用二級映射,先以圖示之:
?
?
?
?
?
??? 如上圖所示,C2是CP15協處理器的一個寄存器,里面存放的是段表的首地址。
??? 虛擬地址被分為三部分,第一部分且稱為段表偏移,用來指示訪問內存的地址在段表中的偏移,這里的段偏移之所以是12位,是因為段表共有4096(12位才能表示)個段表項,每個段有4MB的空間;第二部分用來指示訪問內存的地址在虛擬頁表中的偏移,每個頁表項能代表4KB的空間,;第三部分是要訪問的內存地址相對于確定后的物理頁首地址的偏移量。
注意:段表和虛擬頁表都是存儲在內存中的。
??? 現假設處理器傳送的虛擬地址為0X00101002,轉換成二進制為00000000 00010000 00010000 00000010,可以容易算出段偏移為1,頁表偏移為4,頁偏移2。MMU的處理過程如下:首先根據CP15協處理器的C2寄存器確定段表的首地址,假設這里的段表的基地址是0x30000000,然后通過段偏移1確定要訪問的內存地址在段表中的偏移地址0x30000004,每個段表項中存有虛擬頁表的首地址,由該地址找到虛擬頁表的首地址,假設為0x31000000,再根據頁表偏移確定一個虛擬頁0x31000010,而這個頁中就存有要訪問的內存地址的物理頁的首地址,然后再由頁偏移找到要訪問的時間內存地址,最后再把存在該地址中的數據通過系統總線傳給處理器。
??? 很明顯,處理器訪問一次內存在上述的執行過程中,共需要訪問內存三次,這樣的效率非常的低下。如果要減少訪存的次數,可以將虛擬地址到物理地址的二次映射換為一次映射,即把段表和頁表合二為一,有很多的機器就是采用了這種轉換方式,可這樣又會造成另一個問題,如果采用一級映射,那么映射相同大小4G內存空間一定需要4MB的段表空間,采用二級映射映射4G的內存空間完全映射需要4MB+4KB,表面上二級映射需要的空間更大,在加上比一級映射多一次訪存,好像二級映射完全失去優勢,但我們應該理論實踐相結合,在實際的程序執行中,每一個應用進程都有自己操作的地址空間,這個空間的基本分配方式如下圖所示:
?
?
?
?
??? 在用戶空間內,堆的空間占絕大部分,而堆在使用中存在很大的空洞,不被使用,而棧一般只有一到兩頁,所以在程序的實際運行中,用戶空間基本上都只使用前后的幾個頁,所以在二級映射中可以只映射其中的幾個頁,而在一級映射中必須映射所有的頁,這樣,二級映射中的多一次訪存的代價就微不足道了。
??? 那么,如何提高MMU的映射效率呢,這就是TLB---快表。
?????? TLB其實就是一個小容量的cache,一般大小在4lines~64lines,每行4字節即16bytes~256bytes,每一行存放的是最近使用的映射記錄,使一種全相聯的映射方式。當處理器再次訪問TLB中存有的虛擬地址映射到物理地址的映射記錄時,就可以直接從對應的物理內存中提取想要的數據,這樣,處理器訪存只需要一次訪存就能得到數據,又因為程序訪問具有局部性,所以TLB還是能很大的提高訪存效率的。在有TLB的MMU中,上述的過程中處理器發出的虛擬地址會首先和TLB檢測匹配,如果沒有匹配項才去訪問內存中的主傳輸表,在讀取內存的數據后MMU會將這次的映射記錄放進TLB,如果TLB被存滿,則會采用一種叫RLU算法,替換掉最近最少使用的映射記錄。
??? 那么,在這里還用一個值得注意的地方,在ARM和內存之間還有一個硬件設備,就是cache。雖然我們主要介紹的是MMU,但cache緩存技術在處理器訪存中起到至關重要的作用,它可以極大提高訪問內存的效率,很多處理器系統芯片上集成了多級的cache,這里就簡單介紹一下cache在MMU管理之余所扮演的角色。在處理器發送出虛擬地址后,首先與cache中各項進行匹配,如果命中cache則直接從cache中讀取數據,而不用使用MMU,至于如何匹配cache項,視具體cache結構而定,這里也不做詳細解釋,可以查看相關材料。如果沒有命中cache,則通過MMU將虛擬地址映射到物理地址,到內存中相應的物理地址處讀取數據,然后將該數據所在的一整塊數據讀入cache中,如果cache已滿,則采用預定的替換策略替換掉相應的塊。同樣,由于程序的執行具有局部性,所以cache對訪存效率的提高是顯著的。
?
<2>?存儲器訪問權限的控制
???????當應用程序的所有線程共享同一存儲器空間時,任何一個線程將有意或無意地破壞其它線程的代碼、數據或堆棧。異常線程甚至可能破壞內核代碼或內部數據結構。例如線程中的指針錯誤就能輕易使整個系統崩潰,或至少導致系統工作異常。
????就安全性和可靠性而言,基于進程的實時操作系統(RTOS)的性能更為優越。為生成具有單獨地址空間的進程,RTOS只需要生成一些基于RAM的數據結構并使MMU加強對這些數據結構的保護。基本思路是在每個關聯轉換中“接入”一組新的邏輯地址。MMU利用當前映射,將在指令調用或數據讀寫過程中使用的邏輯地址映射為存儲器物理地址。
??? 簡單說訪問控制機制就是CPU通過目中方法判斷當前程序對內存訪問是否合法(是否有權對內存進行訪問),如果當前的程序沒有權限訪問內存,則CPU將引發一個異常,S3c2440成為Permission fault,例如user級別的程序要對一個system級別的內存區域進行些操作。那么S3c2440的訪問控制機制到底是由什么參與完成的呢?有下面的幾個寄存器的踴躍參與,才使其正常工作:
????? 1?協處理器CP15中的C3:域訪問控制寄存器(domain accesss control register)
????? 2?段描述符中的AP位和domain位
????? 3?協處理器CP15中C1中的S bit和R bit
???? ?4?協處理器CP15中C5,C6
控制訪問:
???????域訪問控制寄存器是訪問控制寄存器,有32個有效位,被分為16個區域,每個區域由兩位組成,有四種組合如下:
???????00:該級別下,內存區域不允許被訪問,任何訪問都會產生domain fault
???????01:該級別下,該內存的訪問必須配合該內存的段描述符中的AP位進行權檢查
???????10:保留
???????11:該級別下:對內存區域的訪問都不進行權限檢查
注意:
???????1?對某個內存區域的訪問是否需要進行權限檢查是由該內存區域的描述符中的domain域決定的。
???????2?某個內存區域的訪問權限是由該內存區域的描述符中的AP位和協處理器CP15中控制寄存器中的S bit和R bit所決定。
?
<3>?設置虛擬存儲空間的緩沖特性
???????這是對cache緩存的是否可用進行的控制。
??????
??? 講解道這里,就基本講完,現在我們來對內存的訪問過程進行總結:
???????1?當處理器產生一個內存訪問請求時,將傳輸的虛擬地址首先傳給cache(根據入口中的C(cachable)控制位和B(bufferable)控制位決定是否允許緩存的存儲訪問,如果不允許緩存,則不對cache進行下面的一切操作),對cache進行匹配,這是由cache的控制器控制完成的,如果命中cache,則將cache中虛擬地址對應的數據取出發送到數據總線上,傳給cpu。
????? 2?如果沒有命中cache,則將虛擬地址傳輸給MMU(如果機器沒有MMU功能或禁止了MMU功能就另當別論),MMU首先遍歷TLB快表,有的系統采用哈佛結構(指令cache和數據cache分開存儲)需要分別遍歷指令TLB和數據TLB,如果命中TLB,則從TLB中取出映射的物理地址,并根據虛擬地址中的頁偏移讀取內存中對應地址中的數據,并把其送到數據總線上,傳給cpu,并將內存中該數據所在的一整塊的數據通過cache內容獲取硬件讀到cache中,如果cache已滿,則采用預定的替換策略替換掉相應的塊。
???3 如果沒有命中TLB,則MMU通過頁表遍歷硬件通過前面敘述的二級映射機制找到物理地址,在讀取內存的數據后MMU會將這次的映射記錄放進TLB,如果TLB被存滿,則會采用一種叫RLU算法,替換掉最近最少使用的映射記錄,并將內存中該數據所在的一整塊的數據通過cache內容獲取硬件讀到cache中,如果cache已滿,則采用預定的替換策略替換掉相應的塊。
?
?? 上面所說的內容沒有包括訪問權限的控制,在這里補充一下:
?? 只有在TLB的匹配時才進行訪問權限的檢查,根據檢查域訪問控制位和訪問權限控制位的結構判斷,如果出現任一種不合法情況,則本次訪問就會產生訪問異常,并終止本次訪問。現在以圖示訪存的過程:
?
?
????????????????????????????????????????????????????????????? 圖3
?
總結
- 上一篇: C/C++堆、栈及静态数据区详解
- 下一篇: 深入了解DSP与ARM的区别与联系