1. 程式人生 > >MIT6.828 虛擬地址轉化為實體地址——二級分頁

MIT6.828 虛擬地址轉化為實體地址——二級分頁

這個分頁,主要是在mit6.828的lab2的背景下來說的。

lab2主要講虛擬記憶體->實體記憶體的變換,通過一定的函式來實現軟體MMU的部分。

整個地址轉化的過程如下圖所示:


首先,明確一點,在程式裡面的所有地址,都是虛擬地址,程式裡面是不會出現實體地址的,就算是實體地址,CPU也會把它當做虛擬地址,通過MMU轉化為實體地址。

通過上面的圖,可以知道,在系統中,CPU得到一個虛擬地址,這個虛擬地址是logical address,通過分段翻譯後,會得到一個線性地址(linear address),線性地址通過分頁翻譯後,就可以得到實體地址了。

在lab2裡,分段機制基本就沒有,所以可以直接認為cpu得到的虛擬地址就是線性地址,只需要經過page translation 就可以得到實體地址了。下面,就來講一下系統分頁的詳細過程。

如下圖所示,就是線性地址通過page director  和 page table轉化成實體地址的過程:

這張圖是從虛擬地址來的,所以包含了分段的過程。其實,分段過程也比較簡單,以C程式舉例,在C中,所有的指標,它的值是一個偏移量,這個偏移量要加上段基址,得到一個線性地址。而前面的偏移量+段基址的過程,就是分段的過程。

在一個程式中,一般分為堆,棧,程式碼段,資料段(.date和.bss等),而指標的值,就是相應的段上的偏移量,如一個指標指向的是一個全域性變數,則它的線性地址位P+.date的基址。這個過程就是分段。在lab2裡面,分段基址好像暫時沒怎麼涉及,所以暫且不管它。好像想在作業系統多是分頁,分段應該不多了。分段和分頁主要的區別就是分頁的頁框是固定大小的,不變的。而分段,每一段的大小都是不定的。分段有利於程式的編譯。這一塊還要在看看書,還是有點不瞭解。

分頁:

在lab2中,主要就是分頁的各種東西。在jos系統裡面,採用二級頁表的分頁形式。即分為page directory 和 page table兩級頁表。

二級頁表好處:在32位系統中,理論上來說,每個程序都擁有獨立的地址空間,其大小是2^32=4G,如果採用一級頁表,則以4K的頁框大小為例,要分配2^20個頁面來給程式使用,每個頁面佔4位元組,則光地址轉換的頁面就需要4*2^20=4M大小(page table的大小)了。這對於以前比較小的記憶體來說,是非常的大的。雖然現在記憶體都有幾個G,但是如果64位作業系統也用一級頁表分頁的話,記憶體塞滿了都放不下轉換頁……。

對於大多數的程式,我並不需要使用4G的記憶體空間,比如編寫一個非常簡單的排序程式,如果資料量不是很大的話,應該總共加起來連1M的記憶體都用不到,這樣,總共實際用到的頁面就只有2^8=256個頁面,佔的記憶體只有256*4=1024=1k,剩下的大部分存這的轉換部分的記憶體都是沒用的,這就表明了一級頁表的空間利用率其實是非常低的,存在著大量的浪費。

所以,要使用二級頁表來進行分頁。二級頁表實在一級頁表的基礎上進一步轉化而來。以32位系統為例,假設頁面大小位4K,一級頁表是把低位的12位作為頁內偏移,高位的20位作為頁索引。而二級頁表,把低位的12位作為頁內偏移,高位的10位作為page directory(PDE)的索引,中間的的10位作為page table(PTE)。所以,以上面那個排序程式為例,如果他只用到了部分的頁面,根據程式頁面的區域性性原理,這些頁面會集中在某幾個”塊“內,所以對於第一級的PDE來說,這些頁面都會集中在少數的幾個PDE中,只需要為那幾個對映到的PDE建立相應的二級頁表(即PTE),而其他沒有被對映到的PDE都不用建立對應的二級頁表,這樣,相對於一級頁表的建立所有的頁面對映,二級頁表只建立相應的頁面對映,雖然也會有所浪費,當相對來說還是節省了大量的記憶體空間。

二級頁表分頁過程:

二級頁表分頁過程比較簡單,首先,PDE的入口地址儲存在CR3暫存器中,讀取CR3暫存器的高位(20位),低12位根據線性地址的高10位得到(由於32位系統中,地址佔4位元組,所以每一個頁表佔4位元組,和陣列是同理:int a[10]; a[1]的地址是a[0]+4而不是+1,所以2^10個頁表需要12位地址)。

通過上述過程得到的PDE,取出存在PDE中的PTE的地址,將PTE的低12位清零,然後中間10位作為索引,得到相應的實體地址的基址,最後通過低12位相加,得到對應的實體地址。轉換過程不涉及很難的地方,比較簡單。

這裡說一下CR3,CR3儲存PDE的地址,所以在程序切換之後,只需要改變CR3中的值,就可以直接切換程序的地址空間,非常的方便。

而上面的PWT表示是否採用回寫策略,若PWT置位,則表示採用通寫策略,即寫快取資料的同時,必須寫外存。PWT=0表示回寫,即寫快取資料,不必改變外存,等到快取頁面被置換,在寫外存。

PCD表示是否開啟快取頁。PCD=1表示禁用快取頁。PCD=0,表示啟用快取頁。這個主要是因為有些頁面對應的I/O埠需要實時採集資料,不能快取資料,因為快取的資料和實時資料有差別,所以需要禁用快取頁。這個在嵌入式裡面應該出現的比較多。

最後一點,這些過程為了保證快速性,全部都是由硬體完成的,而在CR3暫存器,PDE,PGE中儲存的地址,都是實體地址,而不是相對應的虛擬地址。