struct page {
page_flags_t flags; // 頁狀態位圖 (髒、鎖定、複合頁等)
atomic_t _count; // 參考計數 (-1 表示空閒)
atomic_t _mapcount; // 頁表映射計數
unsigned long private; // 私有資料指標
struct address_space *mapping; // 歸屬 address_space (檔案頁)
pgoff_t index; // 在 address_space 中的索引 (檔案偏移)
struct list_head lru; // LRU 鏈表掛載點
void *virtual; // 核心虛擬位址 (高端記憶體為 NULL)
};
struct page → 佔 40MB 核心記憶體 (可接受)。page_address(page) 取得核心邏輯位址;高端記憶體需 kmap() 臨時映射。| 區域 | 物理位址範圍 (x86_32) | 用途 |
|---|---|---|
| ZONE_DMA | < 16 MB | ISA 設備 DMA 必須使用 |
| ZONE_NORMAL | 16 ~ 896 MB | 核心直接永久映射區 (低端記憶體) |
| ZONE_HIGHMEM | > 896 MB | 高端記憶體,需動態映射 (kmap/vmap) 才能由核心存取 |
x86_64 無 HIGHMEM,全部為 ZONE_NORMAL (直接映射)。
| 函式 | 行為 | 返回值 |
|---|---|---|
alloc_pages(gfp_mask, order) | 分配 2^order 頁 | 首頁 struct page* |
alloc_page(gfp_mask) | 分配單頁 | struct page* |
__get_free_pages(gfp_mask, order) | 分配 2^order 頁 | 核心邏輯位址 |
get_zeroed_page(gfp_mask) | 分配單頁並清零 | 核心邏輯位址 |
對應釋放:__free_pages, free_pages, free_page。
GFP 旗標:GFP_KERNEL (可睡眠、一般核心分配)、GFP_ATOMIC (不可睡眠、中斷上下文)、GFP_USER (用戶空間分配)、GFP_HIGHUSER (高端記憶體)、__GFP_ZERO (清零)、__GFP_DMA (ZONE_DMA)。
| 函式 | 連續性 | 最大尺寸 | 釋放 | 適用場景 |
|---|---|---|---|---|
kmalloc(size, flags) | 物理連續 | 128KB (32 頁) | kfree | 高頻小物件、DMA 緩衝區 |
kzalloc(size, flags) | 物理連續 + 清零 | 同上 | kfree | 安全初始化 |
vmalloc(size) | 虛擬連續 (物理離散) | 理論無上限 (受限 vmalloc 區) | vfree | 大型緩衝區、模組載入、核心棧 |
效能:kmalloc走 Buddy + Slab,快;vmalloc需建立頁表映射,TLB 刷新開銷大,分配慢但易得大塊記憶體。
task_struct, inode, dentry)。kmem_cache,含多個 slab (一組連續頁框),Slab 內劃分為物件。kmem_cache_create, kmem_cache_alloc, kmem_cache_free, kmem_cache_destroy。CONFIG_THREAD_STACK_PAGES=1 (4KB) 或 2 (8KB)。kmap(page) / kunmap(page):永久映射 (全域鎖,數量有限)。kmap_atomic(page) / kunmap_atomic():臨時映射 (Per-CPU 槽位,無鎖,中斷上下文可用)。alloc_percpu(type) / free_percpu(ptr):每 CPU 一份實例。get_cpu_var(var) / put_cpu_var(var):存取並禁止/啟用搶佔。每個 VMA (struct vm_area_struct) 描述一段連續虛擬位址區間,屬性含:
vm_start, vm_end)vm_flags : READ/WRITE/EXEC/SHARED/MAYSHARE...)vm_file, vm_pgoff)vm_ops : open/close/fault/mmap...)典型 VMA 類型:
mmap)shmget/mmap MAP_SHARED)malloc/mmap MAP_ANONYMOUS)struct mm_struct {
struct vm_area_struct *mmap; // VMA 單向鏈表 (遍歷用)
struct rb_root mm_rb; // VMA 紅黑樹 (查找用)
atomic_t mm_users; // 使用者空間執行緒計數
atomic_t mm_count; // 核心引用計數
struct list_head mmlist; // 全域 mm_struct 雙向鏈表
// ... pgd, start_code, end_code, start_data, end_data, start_brk, brk, start_stack, arg_start, arg_end, env_start, env_end
};
task_struct->mm 指向進程的 mm_struct;核心執行緒 mm = NULL,借用前一進程的 active_mm 存取核心空間映射。fork():copy_mm() → 複製 mm_struct、頁表、VMA (Copy-on-Write, COW);物理頁框共享,寫入時才分離。clone(CLONE_VM):共享 mm_struct (執行緒模型)。vfork():共享 mm_struct 且父進程阻塞,子進程 exec 或 exit 才喚醒父進程 (極度危險,僅用於 exec 前)。oom_killer,依 oom_score 選擇犧牲進程 (可透過 /proc//oom_score_adj 調整)。