Linux學(xué)習(xí)-內(nèi)存管理篇(二)-MMU介紹

開篇從內(nèi)存管理入手,先了解MMU最基本原理,分析下CPU是如何訪問到內(nèi)存的。

一、MMU介紹

MMU(Memory Management Unit) :內(nèi)存管理單元,它是中央處理器(CPU)中用來管理虛擬存儲器、物理存儲器的控制線路,同時也負(fù)責(zé)虛擬地址映射為物理地址,以及提供硬件機制的內(nèi)存訪問授權(quán)。

二、假設(shè)頁表只有一級

對于一個有MMU的CPU而言,MMU開啟后,CPU是這樣尋址的:CPU任何時候,一切時候,發(fā)出的地址都是虛擬地址,這個虛擬地址發(fā)給MMU后,MMU通過頁表來在頁表里面查出來這個虛擬地址對應(yīng)的物理地址是什么,從而去訪問外面的內(nèi)存條。MMU里面的頁表地址寄存器,記錄了頁表本身的存放位置。

現(xiàn)在我們假設(shè)每一頁的大小是4KB,而且假設(shè)頁表只有一級,這個頁表長成下面這個樣子,頁表的每一行是32個bit。

總結(jié)CPU訪問虛擬地址的流程如下:

依次按順序判斷:是否命中(命中:想要的數(shù)據(jù)在內(nèi)存中)、是否滿足RWX權(quán)限、是否滿足User/Kernel權(quán)限,只要一項不滿足,MMU會給CPU發(fā)出page fault,CPU自動跳到fault的代碼去處理fault。全滿足,那么MMU就去訪問內(nèi)存條上對應(yīng)的地址。

另外,如果頁表只有1級,每4KB的虛擬地址空間就需要頁表里面的一行(32bit),那么CPU要覆蓋到整個4GB的內(nèi)存,就需要這個頁表的大小是:4MB。

所以,這個頁表的大小是4MB,覆蓋了整個0-4GB的虛擬地址空間,任何一個虛擬地址,都可以用地址的高20位(由于一頁是4KB,低12位就是葉內(nèi)偏移了),作為頁表這個表的行號去讀對應(yīng)的頁表項。

這個查水表的過程,由MMU硬件自動完成。

現(xiàn)在我們假設(shè)在Linux里面有2個進(jìn)程,一個是QQ,一個是Firefox,他們的頁表分別如下:

當(dāng)CPU在執(zhí)行QQ的時候,Linux會把QQ的頁表的物理地址255MB,填入MMU的頁表地址寄存器,于是這個時候,QQ的頁表生效。根據(jù)頁表內(nèi)容,CPU如果訪問4KB這個虛擬地址的話,MMU訪問內(nèi)存條的6MB物理地址;CPU如果訪問8KB這個虛擬地址的話,MMU訪問內(nèi)存條的8MB物理地址;CPU如果訪問3GB這個虛擬地址的話,MMU訪問內(nèi)存條的0MB物理地址;

當(dāng)CPU在執(zhí)行Firefox的時候,Linux會把Firefox的頁表的物理地址280MB,填入MMU的頁表地址寄存器,于是這個時候,F(xiàn)irefox的頁表生效,QQ的頁表淡出江湖。根據(jù)頁表內(nèi)容,CPU如果訪問4KB這個虛擬地址的話,MMU訪問內(nèi)存條的100MB物理地址;CPU如果訪問8KB這個虛擬地址的話,MMU訪問內(nèi)存條的200MB物理地址;CPU如果訪問3GB這個虛擬地址的話,MMU訪問內(nèi)存條的0MB物理地址。

上面我們發(fā)現(xiàn)一個共同點,QQ和Firefox去訪問3GB虛擬地址的時候,最終MMU訪問的都是0MB這個物理地址,具體原因非常簡單,QQ和Firefox,這2張頁表里面,3GB/4KB這一行,里面填的是完全一樣的東東。

三、多級頁表:真實的存在

上面我們發(fā)現(xiàn),如果采用一級頁表的話,每個進(jìn)程都需要1個4MB的頁表,這個空間浪費還是很大,于是我們可以采用二級或者三級頁表。舉例如下,假設(shè)我們用地址的高10位作為一級頁表的索引,中間10位作為2級頁表的索引。CPU訪問虛擬地址16,這個地址如果分解為10/10/12位的話,就是這個樣子:

那么MMU會用0這個下標(biāo)去訪問一級頁表(一級頁表的地址填入MMU的頁表地址寄存器)的第0行,第0行的內(nèi)容寫的是2MB(此處不再是最終的物理地址,而是二級頁表的物理地址),證明二級頁表的地址在2MB,于是MMU自動去以中間的10位作為下標(biāo),去查詢位置在2MB的二級頁表,在2級頁表里面,最終查到第0頁(地址范圍0x00000000~0x00000FFF)這個虛擬地址的物理地址是1GB,于是MMU去訪問內(nèi)存條的1GB+16這個物理地址。

據(jù)以上分析,1級頁表占據(jù)的內(nèi)存是2的10次方,再乘以4,即4KB。而每個二級頁表,也是2的10次方,再乘以4,即4KB。分級機制的主要好處是,二級頁表不是一定存在了,比如一級頁表的第2行不命中,也即如下地址都無效的話:

那么這一行對應(yīng)的二級頁表,就整個都不需要了,于是就省掉了這段區(qū)間4KB二級頁表的內(nèi)存占用。頁表當(dāng)然還有是三級甚至更多。

至于有多級頁表的時候,其實MMU也只需要知道一級頁表的基地址即可。每次切換進(jìn)程的時候,把一級頁表的地址重新填入MMU,把新的進(jìn)程的頁表激活即可。

轉(zhuǎn)自宋寶華老師
宋寶華: CPU是如何訪問到內(nèi)存的?--MMU最基本原理

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容