歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> 關於Linux

Linux內存管理:高端內存的映射方式

高端內存是指物理地址大於 896M 的內存。

對於這樣的內存,無法在“內核直接映射空間”進行映射。

為什麼?

因為“內核直接映射空間”最多只能從 3G 到 4G,只能直接映射 1G 物理內存,對於大於 1G 的物理內存,無能為力。

實際上,“內核直接映射空間”也達不到 1G, 還得留點線性空間給“內核動態映射空間” 呢。

因此,Linux 規定“內核直接映射空間” 最多映射 896M 物理內存。

對於高端內存,可以通過 alloc_page() 或者其它函數獲得對應的 page,但是要想訪問實際物理內存,還得把 page 轉為線性地址才行(為什麼?想想 MMU 是如何訪問物理內存的),也就是說,我們需要為高端內存對應的 page 找一個線性空間,這個過程稱為高端內存映射。

高端內存映射有三種方式:

1、映射到“內核動態映射空間”

這種方式很簡單,因為通過 vmalloc() ,在“內核動態映射空間”申請內存的時候,就可能從高端內存獲得頁面(參看 vmalloc 的實現),因此說高端內存有可能映射到“內核動態映射空間” 中。

2、永久內核映射

如果是通過 alloc_page() 獲得了高端內存對應的 page,如何給它找個線性空間?

內核專門為此留出一塊線性空間,從 PKMAP_BASE 到 FIXADDR_START ,用於映射高端內存。在 2.4 內核上,這個地址范圍是 4G-8M 到 4G-4M 之間。這個空間起叫“內核永久映射空間”或者“永久內核映射空間”

<!——[endif]——>這個空間和其它空間使用同樣的頁目錄表,對於內核來說,就是 swapper_pg_dir,對普通進程來說,通過 CR3 寄存器指向。

通常情況下,這個空間是 4M 大小,因此僅僅需要一個頁表即可,內核通過來 pkmap_page_table 尋找這個頁表。

通過 kmap(), 可以把一個 page 映射到這個空間來

<!——[endif]——>由於這個空間是 4M 大小,最多能同時映射 1024 個 page。因此,對於不使用的的 page,及應該時從這個空間釋放掉(也就是解除映射關系),通過 kunmap() ,可以把一個 page 對應的線性地址從這個空間釋放出來。

3、臨時映射

內核在 FIXADDR_START 到 FIXADDR_TOP 之間保留了一些線性空間用於特殊需求。這個空間稱為“固定映射空間”

在這個空間中,有一部分用於高端內存的臨時映射。

這塊空間具有如下特點:

<!——[if !supportLists]——>1、 <!——[endif]——>每個 CPU 占用一塊空間

<!——[if !supportLists]——>2、 <!——[endif]——>在每個 CPU 占用的那塊空間中,又分為多個小空間,每個小空間大小是 1 個 page,每個小空間用於一個目的,這些目的定義在 kmap_types.h 中的 km_type 中。

當要進行一次臨時映射的時候,需要指定映射的目的,根據映射目的,可以找到對應的小空間,然後把這個空間的地址作為映射地址。這意味著一次臨時映射會導致以前的映射被覆蓋。

通過 kmap_atomic() 可實現臨時映射。

下圖簡單簡單表達如何對高端內存進行映射

Copyright © Linux教程網 All Rights Reserved