linux 核心學習之記憶體管理 未完待續

2021-06-22 13:30:33 字數 2542 閱讀 8283

1 相關概念

mmu:mmu是memory management unit的縮寫,中文名是

記憶體管理

單元,它是

**處理器

(cpu)中用來管理

虛擬儲存器

、物理儲存器的控制線路,

同時也負責

虛擬位址

對映為實體地址

,以及提供硬體機制的記憶體訪問授權。 頁:

記憶體管理(物理頁)的基本單位

,mmu通常以頁為單位進行處理,通常32位體系結構支援4kb的頁,64位體系結構一般支援8kb的頁。

核心中以struct page 表示系統中的每個物理頁。page結構體的virtual域是頁的虛擬位址(就是頁在虛擬記憶體中的位址)。

區:核心使用區對功能相似的頁進行分組。linux主要使用了四種區:

zone_dma:這個區包含的頁用來執行dma操作。

zone_dma32:用來執行dma操作,與上面不同之處在於,此區的頁面只能被32位裝置訪問。

zone_normal:這個區包含的都是能正常對映的頁。

zone_highem:這個區包含「高階記憶體」,其中的頁並不能永久地對映到核心位址空間。

使用者空間:程序空間中0~3g部分,對應程序,

當程序切換改變時,使用者空間會隨之發生變化。使用者程序只能訪問使用者虛擬空間而無法訪問核心空間。

核心空間:4g的使用者空間中3g~4g的部分,核心負責對映,是固定的,不隨程序切換而改變。

tlb(translation lookaside buffer):一種硬緩衝區,用來快取虛擬位址到實體地址的對映關係,大大提供了系統的效能。

2.記憶體分配介面

以頁為單位的記憶體分配介面:

alloc_pages 和

page_address,其中

獲得填充為0的頁是:

get_zeroed_page

以位元組為單位的記憶體分配介面:

malloc:使用者空間申請動態記憶體,使用free釋放記憶體

。malloc 分配的內存在虛擬位址空間是連續的,但是其在實體地址(即在物理ram中)並不一定是連續的。linux核心,c庫的malloc函式通過brk()和mmap()兩個系統呼叫來實現。

kmalloc :與使用者空間的malloc類似,用於獲得以位元組為單位的一塊核心記憶體,所分配的區域不僅虛擬位址是連續的,實體地址上是連續的。效能較後面介紹的vmalloc 高。

kmalloc函式使用較多,返回的是乙個指向記憶體塊的指標,其記憶體塊至少要有size大小。kfree函式釋放由kmalloc分配出來的記憶體塊。

kmalloc 分配的區域位於物理記憶體對映區(3g~3g+64m的區域)。

出錯時,返回的是null(除非沒有足夠的記憶體可用,否則核心總能分配成功)。在呼叫kmalloc呼叫之後,

必須檢查返回的是不是null,

如下:

struct dog *p;

p = kmalloc(sizeof(stuct dog),gfp_kernel);/

/第二個引數gfp_fernel是分配器的標誌,下文中有介紹

if(!p)

/*處理錯誤*/

vmalloc:與kmalloc不同的是,vmalloc所分配的區域在物理不是連續的,需要建立頁表項以把物理上不連續的頁轉換為虛擬位址空間上連續的頁,因此與kmalloc相比,效率較低。

同vfree對應。vmalloc 分配的區域(位於核心空間:3g+64m+8m(大概)~接近4g)與kmalloc 分配的區域不在同乙個區域。

3. 虛擬位址到實體地址的轉換

應用程式操作的物件是對映到物理記憶體之上的虛擬記憶體,但是處理器直接操作的卻是物理記憶體。所以當用程式訪問乙個虛擬位址時,首先必須將虛擬位址轉化成實體地址,然後處理器才能解析位址訪問請求。位址的轉換工作需要通過查詢頁表才能完成,概括的講,位址轉換需要將虛擬位址分段,使每段虛位址都作為乙個索引指向頁表,而頁表項則指向下一級別的頁表或者指向最終的物理頁面。

每個程序都有自己的頁表。程序描述符號的pgd域指向的就是程序的頁全域性目錄。注意,虛擬位址對映到頁之前必須先分配物理頁---即必須先從核心獲取空閒頁,並建立頁表。因此需要了解核心管理物理記憶體(頁管理)的機制。

4 程序位址空間的管理

5 分配器標誌

分為三類:行為修飾符、區修飾符及型別標誌。作為kmalloc函式的乙個引數使用。

行為修飾符:表示核心應當如何分配所需的記憶體,例如分配記憶體的過程中不能睡眠。

區修飾符:表示記憶體區應該從何處分配,核心優先從zone_normal開始。通常不需要指定。

型別標誌:指定所需的行為和區描述符以完成特殊型別的處理(核心使用型別標誌的做法既簡單又不容易出錯誤,而不是直接使用用到的多個描述符

)。通常使用的是gfp_kernel或者gfp_atomic。

例如最常用的標誌gfp_kernel,實際上是_gfp_wait|_gfp_io|_gfp_fs)的組合,呼叫可能祖塞,表示能睡眠的記憶體分配(表示核心執行呼叫者睡眠)。

gfp_atomic:表示不能睡眠的記憶體分配(核心不能讓呼叫這休眠),因此它分配成功的機會較小(與gfp_gernel)相比。但是,在當前**(例如中斷處理程式、軟中斷和tasklet)不能睡眠時,只能選擇gfp_atomic.

linux核心學習筆記之記憶體管理

linux核心把物理頁作為記憶體管理的基本單位。每一頁的大小根據系統架構不同有所區別,32位系統下為4kb,64位系統下為8kb。記憶體管理單元 mmu 以頁為單位來管理系統中的頁表,負責虛擬位址到實體地址的轉換,使用者所使用的記憶體位址一般都是虛擬位址。核心中頁的結構體中比較重要的成員為 stru...

linux核心學習 記憶體管理

核心把物理頁作為記憶體管理的基本單位。32位系統 4k 頁 64位系統 8k 頁 由於硬體限制,核心不能對所有頁一視同仁。linux必須處理如下硬體存在的缺陷而引起的記憶體定址問題 linux主要使用了四種區 zone dma 這個區包含的頁只能用來執行dma操作 zone dma32 和zone ...

核心學習之記憶體定址(一)

端選擇符和段暫存器 邏輯位址 48位 由段選擇符 16位 和偏移量 32位 組成 t1 0表示gdt,1表示ldt 段暫存器 16位 用來儲存段選擇符,由於段描述符為8位元組,因此,索引號只需要13位元組即可 cs 段暫存器,指向包含程式指令的段。它包含兩位的字段 cpl 0表示核心態,3表示使用者...