天天看點

Linux核心位址空間分布

在32位系統裡,Linux核心位址空間是指0xC0000000開始到0xFFFFFFFF總量為1G的高端記憶體位址空間,而使用者空間是0x00000000至0xBFFFFFFF的3G虛拟存儲空間。作業系統和驅動程式運作在核心空間,應用程式運作在使用者空間。

Linux核心位址空間分布

核心位址映射有下幾種模式

1、直接映射區:核心将核心空間前896M和實體空間的前896M進行直接映射。即對于核心空間前896M記憶體有:Vaddr= 0xC0000000 + Paddr。高端記憶體是指896M開始到1G的虛拟位址空間。引入高端記憶體映射這樣一個概念的主要原因就是我們所安裝的記憶體大于1G時,核心的1G線性位址空間無法建立一個完全的直接映射來觸及整個實體記憶體空間,而對于80x86開啟PAE的情況下,允許的最大實體記憶體可達到64G,是以核心将自己的最後128M的線性位址空間騰出來,用以完成對高端記憶體的暫時性映射。而在64位的系統上就不存在這樣的問題了,因為可用的線性位址空間遠大于可安裝的記憶體。

2、動态記憶體映射區:該區域由核心函數vmalloc來配置設定,特點是:線性空間連續,但是對應的實體空間不一定連續。vmalloc配置設定的線性位址所對應的實體頁可能處于低端記憶體,也可能處于高端記憶體。

3、永久記憶體映射區:核心專門為此留出一塊線性空間,從 PKMAP_BASE 到 FIXADDR_START ,用于映射高端記憶體。在 2.6核心上,這個位址範圍是 4G-8M 到 4G-4M 之間,叫做”永久核心映射空間”。這個空間和其它空間使用同樣的頁目錄表,對于核心來說,就是 swapper_pg_dir,對普通程序來說,通過 CR3 寄存器指向。通常情況下,這個空間是 4M 大小,是以僅僅需要一個頁表即可,核心通過來 pkmap_page_table 尋找這個頁表。通過 kmap(),可以把一個 page 映射到這個空間來。由于這個空間是 4M 大小,最多能同時映射 1024 個 page。是以,對于不使用的的 page,及應該時從這個空間釋放掉(也就是解除映射關系),通過 kunmap() ,可以把一個 page 對應的線性位址從這個空間釋放出來。

4、固定記憶體映射區:核心在FIXADDR_START 到 FIXADDR_TOP 之間保留了一些線性空間用于特殊需求。這個空間稱為”固定映射空間”在這個空間中,有一部分用于高端記憶體的臨時映射。這塊空間具有如下特點:

(1)每個CPU 占用一塊空間

(2)在每個CPU 占用的那塊空間中,又分為多個小空間,每個小空間大小是1 個 page,每個小空間用于一個目的,這些目的定義在kmap_types.h 中的km_type 中。

當要進行一次臨時映射的時候,需要指定映射的目的,根據映射目的,可以找到對應的小空間,然後把這個空間的位址作為映射位址。這意味着一次臨時映射會導緻以前的映射被覆寫。通過kmap_atomic() 可實作臨時映射。

繼續閱讀