Linux 記憶體管理 高階記憶體的對映方式

2021-06-20 05:20:25 字數 2442 閱讀 8286

解釋一:

核心在 fixaddr_start 到 fixaddr_top 之間保留了一些線性空間用於特殊需求。這個空間稱為「固定對映空間」

在這個空間中,有一部分用於高階記憶體的臨時對映。

這塊空間具有如下特點:

1、 每個 cpu 占用一塊空間

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

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

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

下圖簡單簡單表達如何對高階記憶體進行對映

解釋二:

解釋三:

vmalloc_reserve和896m

linux 核心虛擬位址空間到實體地址空間一般是固定連續影射的。

假定機器記憶體為512m,

從3g開始,到3g + 512m 為連續固定影射區。zone_dma, zone_normal為這個區域的。固定影射的vaddr可以直接使用(get a free page, then use pfn_to_virt()等巨集定義轉換得到vaddr)或用kmalloc等分配. 這樣的vaddr的物理頁是連續的。得到的位址也一定在固定影射區域內。

如果記憶體緊張,連續區域無法滿足,呼叫vmalloc分配是必須的,因為它可以將物理不連續的空間組合後分配,所以更能滿足分配要求。vmalloc可以對映高階頁框,也可以對映底端頁框。vmalloc的作用只是為了提供邏輯上連續的位址。。 。

但vmalloc分配的vaddr一定不能與固定影射區域的vaddr重合。因為vaddr到物理頁的影射同時只能唯一。所以vmalloc得到的 vaddr要在3g + 512m 以上才可以。也就是從vmalloc_start開始分配。 vmalloc_start比連續固定影射區大最大vaddr位址還多8-16m(2*vmalloc_offset)--有個鬼公式在

#define vmalloc_offset   8*1024

#define vmalloc_start   (high_memory - 2*vmalloc_offset) & ~(vmalloc_offset-1)

high_memory 就是固定影射區域最高處。

空開8-16m做什麼? 為了捕獲越界的mm_fault.

同樣,vmalloc每次得到的vaddr空間中間要留乙個page的空(空洞),目的和上面的空開一樣。你vmalloc(100)2次,得到的2個位址中間相距8k。

如果連續分配無空洞,那麼比如

p1=vmalloc(4096);

p2=vmalloc(4096);

如果p1使用越界到p2中了,也不會mm_****t. 那不容易debug.

下面說明vmalloc_reserve和896m的問題。

上面假設機器物理512m的case. 如果機器有1g物理記憶體如何是好?那vmalloc()的vaddr是不是要在3g + 1g + 8m 空洞以上分配?超過定址空間了嗎。

這時,4g 下面保留的vmalloc_reserve 128m 就派上用場了。

也就是說如果物理記憶體超過896m, high_memory也只能在3g + 896地方。可定址空間最高處要保留vmalloc_resreve 128m給vmalloc用。

所以這128m的vaddr空間是為了vmalloc在物理超過了896m時候使用。如果物理僅僅有512m, 一般使用不到。因為vmalloc_start很低了。如果vmalloc太多了才會用到。

high_memory在arch/i386/kernel, mm的初始化中設定。根據物理記憶體大小和vmalloc_reserve得到數值.

所以說那128m的核心線性位址僅僅是為了影射1g以上的物理記憶體的不對的。如果物理記憶體2g,1g以下的vmalloc也用那空間影射。總之,核心的高階線性位址是為了訪問核心固定對映以外的記憶體資源

看vmalloc分配的東西可以用

show_vmalloc()

} 使用者空間當然可以使用高階記憶體,而且是正常的使用,核心在分配那些不經常使用的記憶體時,都用高階記憶體空間(如果有),所謂不經常使用是相對來說的,比如核心的一些資料結構就屬於經常使用的,而使用者的一些資料就屬於不經常使用的。

使用者在啟動乙個應用程式時,是需要記憶體的,而每個應用程式都有3g的線性位址,給這些位址對映頁表時就可以直接使用高階記憶體。

而且還要糾正一點的是:那128m線性位址不僅僅是用在這些地方的,如果你要載入乙個裝置,而這個裝置需要對映其記憶體到核心中,它也需要使用這段線性位址空間來完成,否則核心就不能訪問裝置上的記憶體空間了。

總之,核心的高階線性位址是為了訪問核心固定對映以外的記憶體資源

實際上高階記憶體是針對核心一段特殊的線性空間提出的概念,和實際的物理記憶體是兩碼事。程序在使用記憶體時,觸發缺頁異常,具體將哪些物理頁對映給使用者程序是核心考慮的事情。在使用者空間中沒有高階記憶體這個概念。

c語言學習筆記 記憶體管理 linux的記憶體映像

程式在記憶體中的儲存形式 程式儲存在flash中 程式在記憶體中主要分為以下幾段 段,資料段,唯讀資料段,bss段,堆,棧,檔案對映區,核心對映區 作業系統核心 程式一般存放在 段,在linux中又稱為文字段 資料段存放的一般是靜態變數和被初始化為非零值的全域性變數 bss段存放的是被初始化為零的全...

Linux記憶體管理之高階記憶體對映

分析完linux記憶體管理的基本概念與實現之後,就可以接著分析使用者空間與核心空間的互動操作了。brk系統呼叫屬於那種常用但是 可見度 不高的操作,常用於使用者空間堆的管理 請參閱本站的 中的malloc機制分析 一文 brk在使用者空間的介面為int brk void end data segme...

Linux記憶體管理 核心高階記憶體

linux核心位址對映模型 x86 cpu採用了段頁式位址對映模型。程序 中的位址為邏輯位址,經過段頁式位址對映後,才真正訪問物理記憶體。段頁式機制如下圖 linux核心位址空間劃分 通常32位linux核心位址空間劃分0 3g為使用者空間,3 4g為核心空間。注意這裡是32位核心位址空間劃分,64...