Linux內存管理的基本框架??
Linux內核的映射機制設計成三層,在頁面目錄和頁面表中間增設了一層“中間目錄”。
在代碼中,頁面目錄稱為PGD,中間目錄稱為PMD,而頁面表稱為PT。
PT中的表項稱為PTE,PTE是“Page Table Entry”的縮寫。
PGD、PMD和PT均為數組。
在邏輯上也把線性地址從高位到低位劃分成4個位段。
4G字節虛存空間
Linux內核將這4G字節的空間分成兩部分:
將最高的1G字節(從虛地址0xC0000000至0xFFFFFFFF)用於內核本身,稱為“系統空間”。
將較低的3G字節(從虛地址0x0至0xBFFFFFFFF)用作各個進程的“用戶空間”。
系統空間由所有進程共享。
每當一個進程通過系統調用進入了內核,該進程就在共享的系統空間中運行,不再有其自己的獨立空間。
雖然系統空間占據了每個虛存空間中最高的1G字節,在物理的內存中卻總是從最低的地址(0)開始。
對於內核來說,其地址的映射是很簡單的線性映射,0xC0000000
此位移稱為PAGE_OFFSET,定義於文件include/asm-i386/page.h中。
PAGE_OFFSET也代表著用戶空間的上限,常數TASK_SIZE就是通過它定義的。
對於系統空間而言,給定一個虛地址x,其物理地址是從x中減去PAGE_OFFSET;相對應地,給定一個物理地址x,其虛地址是x+PAGE_OFFSET。
_pa()只是為內核代碼中當需要知道與一個虛地址對應的物理地址時提供方便。
例如,在切換進程的時候要將寄存器CR3設置成指向新進程的頁面目錄PGD,而該目錄的起始地址在內核代碼中是虛地址,但CR3所需要的是物理地址,這時候就要用到_pa()。
每個進程的局部段描述表LDT
每個進程還有一個TSS結構(任務狀態段)
每個進程都要在全局段描述表GDT中占據兩個表項。
段寄存器中用作GDT表下標的位段寬度是13位,所以GDT中可以有8192個描述項。
一些系統開銷:(GDT中的第2項和第3項分別用於內核的代碼段和數據段,第4項和第5項永遠用於當前進程的代碼段和數據段,第1項永遠是0,等等)
有8180個表項可供使用,所以系統中最大的進程數量是4090。
①物理內存管理:
Linux內存最小管理單位為頁(page),通常一頁為4K。初始化時,linux會為每個物理內存也建立一個
②進程內存管理:
Linux進程通過vma進行管理,每個進程都有一個task_struct結構體進行維護,其中的mm_struct結構體管理這進程的所有內存。Mm_struct中維護者一個vma鏈表,其中的每一個vma節點對應著一段連續的進程內存。這裏的連續是指在進程空間中連續,物理空間中不一定連續。如果使用malloc等申請一段內存,則內核會給進程增加vma節點。
--
Linux內存管理的基本框架??