linux記憶體對映

2021-09-23 23:19:19 字數 2388 閱讀 1257

記憶體管理分為對連續物理記憶體區管理和非連續記憶體區管理,本文主要講解連續的物理記憶體區管理的技術中所涉及到的核心線性位址空間對映的相關知識。涉及到的東西有:頁框,管理區(高階記憶體,低端記憶體),高階記憶體對映等,這些知識是掌握夥伴系統演算法和slab分配器的基礎。

一、頁框   

頁框為物理記憶體分配的基本單元,現代32位計算機一般設定為4kb(見上文計算機記憶體定址)。核心必須記錄每個頁框的當前狀態,例如:頁框屬於哪個經常的頁,哪些頁框抱哈的是核心**或核心資料等,由此linux定義了乙個頁框的描述符:page。linux用page來儲存頁框的狀態資訊,所有的page都存放在mem_map陣列中,以便管理記憶體。

二、管理區  

很顯然,如果計算機對記憶體的使用沒有區別,那麼直接使用頁框管理記憶體是最為方便的。但是,由於計算機體系結構的的硬體限制:

(1)isa匯流排的直接記憶體訪問(dma)處理器只能對隨機儲存器(ram)的前16mb定址。

(2)具有大容量的ram的32位計算機中,cpu不能直接訪問所有的物理記憶體!

所以,由於上述的原因,linux將物理記憶體劃分為3個管理區:

(1)zone_dma:包含低於16m的記憶體頁框,只有它能夠作用於dma;

(2)zone_normal:包含高於16m且低於896m的記憶體頁框;

(3)zone_highmem:包含從896m開始高於896m的記憶體頁框。

zone_dma和zone_normal我們一般稱之為低端記憶體(896mb),zone_highmem稱之為高階記憶體。高、低端記憶體的分類主要在於區分物理記憶體位址是否可以直接對映到核心線性位址空間中。問題來了,高、低端記憶體和核心的線性空間的對映是什麼樣的呢?

為了能使在核心態的所有程序能使用更多的物理記憶體,linux採取了一種變通的形式:它將1g核心線性位址空間分為2部分,第一部分為1g的前896m,這部分核心線性空間與物理記憶體的0~896m一一對映,第二部分為1g的後128m的線性空間,拿來動態對映剩下的所有物理記憶體。

看到這裡應該幾乎懂了為什麼要有高階記憶體和低端記憶體的區分了!核心線性位址空間的前896m對映的就是我們的低端頁框記憶體(zone_dma和zong_normal),而且是直接對映;核心線性位址空間的後128m對映的是我們的高階頁框記憶體(zong_highmeme)。

上述的三個管理區,每個管理區都有自己的管理區描述符,管理區描述符的位址存放在zone_table陣列中。核心呼叫乙個記憶體分配函式時,必須指明請求頁框所在的管理區。

為滿足記憶體分配請求,記憶體管理區使用兩種方式來保證:

(1)當空閒記憶體不足時,發出請求的核心控制路徑阻塞,知道有記憶體釋放,才分配。

(2)如果核心控制路徑不能被阻塞(原子記憶體分配請求),就從頁框池中分配記憶體。

頁框池為記憶體保留的記憶體,由zone_dma和zone_normal來共同分配,分配的頁框池大小為:sqrt(16*直接對映記憶體) kb

三、高階記憶體頁框的核心對映

1、永久核心對映

永久核心對映允許核心建立高階頁框到核心位址空間的長期對映。他使用主核心頁表中乙個專門的頁表,其頁表位址存放在pkmap_page_table中,頁表包含512項或1024項,因此,核心一次最多訪問2m或4m的高階記憶體(位址範圍是 4g-8m 到 4g-4m 之間,這個位址空間起叫「核心永久對映空間」或者「永久核心對映空間」)。

永久核心對映通過kmap()函式建立,**:

kmap()

對於不使用的的 page,及應該時從這個空間釋放掉(也就是解除對映關係),通過 kunmap() ,可以把乙個 page 對應的線性位址從這個空間釋放出來。

2、臨時核心對映

臨時核心對映可用在中斷處理程式和可延遲函式的內部,它從不阻塞當前程序。

核心在 fixaddr_start 到 fixaddr_top 之間保留了一些線性空間用於特殊需求。這個空間稱為「固定對映空間」,在這個空間中,有一部分用於高階記憶體的臨時對映。這塊空間具有如下特點:

(1) 每個 cpu 占用一塊空間;

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

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

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

kmap_atomic

最後,給一張頁框頁管理區的圖,加深核心線性位址空間對映的印象:

參考:1、深入理解linux核心

2、linux 記憶體管理 -- 高階記憶體的對映方式 

3、linux核心--核心位址空間分布和程序位址空間 

4、linux記憶體管理** 

Linux記憶體對映

使用記憶體對映處理大檔案很方便,在windows系統中,實現了這樣的藉口。在linux中我們也可以通過mmap函式來實現。以下內容完全參考自 如有冒犯,請諒解 mmap函式實現把乙個檔案對映到乙個記憶體區域,從而我們可以像讀寫記憶體一樣讀寫檔案,他比單純呼叫read write也要快上許多。在某些時...

Linux記憶體對映

本文討論的linux版本是linux 2.6.26.5,體系結構是smdk2410,採用arm s3c2410。在該版本中虛擬位址是32位位址,採用四級頁表結構,依次是 pgd pud pmd pte offset page shift pmd shift pud shift pgdir shift...

linux記憶體對映

記憶體管理分為對連續物理記憶體區管理和非連續記憶體區管理,本文主要講解連續的物理記憶體區管理的技術中所涉及到的核心線性位址空間對映的相關知識。涉及到的東西有 頁框,管理區 高階記憶體,低端記憶體 高階記憶體對映等,這些知識是掌握夥伴系統演算法和slab分配器的基礎。一 頁框 頁框為物理記憶體分配的基...