2021-05-12 14:32:11
Linux 0.12核心與現代核心在記憶體管理上的區別
Linux 0.12核心的記憶體管理比較簡單粗暴,核心只用了一個頁目錄,只能對映4G的線性空間,所以每個進程的虛擬空間(邏輯空間)只能給到64M,最多64個進程;每個進程都有對應的任務號nr,當一個進程需要分配進程空間時,只需要nr乘以64M就可以得出該進程空間的線性起始地址。然後該進程的程式碼段、資料段描述符裡面的基址欄位會被設定為(nr x 64M),同時可以為進程分配頁目錄項和頁目錄表用以承載對映關係。
之後如果進程要存取自己空間內的某個地址時就會首先用基地址與程式內32位元偏移地址(邏輯地址)合成出線性地址,這個合成出來的線性地址一定在(段基址)~(段基址+段限長)之間,也就是(nr x 64M ~ nr x 64M+64M)之間。然後用這個線性地址遵循:“頁目錄項-頁表-頁表表項”這樣的順序找到對應的頁表表項,也就找到了實體地址,就可以真正的存取資料了。
但是在現代核心裡,記憶體管理有很多不同。
首先,線性地址空間不會改變,32位元CPU可定址4G線性空間。這個是唯一的。
但是每個進程都有自己各自獨立的4G虛擬空間,那麼這是如何做到的呢?其實是每個進程給它一個自己的頁目錄,這樣每個進程就能擁有4G的虛擬空間(邏輯空間)了。
注意:0.12核心兩個進程各自合成出的線性地址一定不相同,因為每個進程佔據線性空間的不同區域。但是現代核心裡,A、B兩個進程可能合成出相同的線性地址,因為每個進程都有4G的虛擬空間,也就是說虛擬空間和線性空間對等了。但是由於兩個進程的頁目錄和頁表都不同,所以這兩個進程會把各自合成出的數值相等的線性地址,對映到不同的實體地址。也就是兩者線性空間到物理空間的對映是不同的。換句話說在現代核心裡,虛擬空間(邏輯空間)和線性空間幾乎成了一個概念,以下不作區分。
舉個例子,即使A和B進程同時存取各自線性空間的0x0804800地址處,分段分頁地址變換機制也會把0x0804800這個線性地址對映到不同的實體地址上去。而這個過程,進程自己是看不到的,A和B都認為自己成功存取了0x0804800這個地址,但是實際上,他們存取的是各自線性空間裡“數值相等的”線性地址,最終這兩個“數值上相等”的線性地址將對映到不同的的實體記憶體地址處。這就實現了進程隔離。
每個進程都具備4G的線性空間(虛擬空間),進程的線性空間之間相互隔離,互不干涉,每個進程都在自己的世界裡幹活。
上面說的都是從作業系統原理的角度說的,放到具體的Linux作業系統上會有點不同。因為Linux核心裡面規定,雖然每個進程各自擁有4G的線性空間,但是他們並不能隨意使用這全部的4個G。0-3G是使用者空間,的確是可以自由使用的,但是3G-4G之間核心空間,不能被隨意使用。所以,上面的理論可以完善為,每個進程都有一個大小為4G的線性空間,這4G的線性空間分為兩部分:
大小為3G的使用者空間,各進程在“特權級3級”下可以自由獨立使用,各進程的這塊空間是完全獨立的互不影響的,是指向實體記憶體不同位置的。
大小為1G的核心空間,各進程在“特權級0級”下才可以使用這塊空間,各進程的這塊空間不是獨立的,是指向同一實體記憶體位置的。也就是說是所有進程共用的。
本文永久更新連結地址:http://www.linuxidc.com/Linux/2015-12/126540.htm
相關文章