Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學

Linux 內核啟動階段保留大塊內存的三種方法

編輯:Linux 系統常見問題解答

方法對比

方法原理優點缺點/難點推薦場景
reserve_bootmem(addr, size, flags)在 bootmem 分配器中標記物理頁面保留精確控制物理地址範圍實測難以成功,需極早調用 (arch 代碼),文檔稀缺極早期、特定物理地址保留 (如 firmware reserved)
alloc_bootmem(size)從 bootmem 分配內存,返回線性地址簡單,在 start_kernel 中調用即可返回線性地址,後續如何映射到內核/用戶空間無現成 API,需手動建頁表內核內部臨時大緩衝區,不需用戶映射
內核啟動參數 mem=XXX告知內核僅使用 XXX 內存,其餘物理內存不納入內核管理最簡單,無需修改代碼;驅動中用 ioremap 映射內核空間,mmap 映射用戶空間需知曉物理內存總量並精確計算;內核可用內存減少設備驅動保留 DMA 緩衝區、共享內存、安全隔離區

方法 3 實戰步驟 (以 ARM 板 256MB 內存,保留 64MB 為例)

  1. 修改啟動參數 (U-Boot bootargs 或 GRUB kernel 行):
    mem=192M   /* 內核只見 192MB,高 64MB (0x0C000000 - 0x0FFFFFFF) 保留 */
    
  2. 驅動中映射保留區:
    
    // 內核空間映射
    void *kern_vaddr = ioremap(0x0C000000, 64*1024*1024);
    // 用戶空間映射 (mmap file operations)
    int my_mmap(struct file *filp, struct vm_area_struct *vma) {
        unsigned long pfn = 0x0C000000 >> PAGE_SHIFT;
        return remap_pfn_range(vma, vma->vm_start, pfn, vma->vm_end - vma->vm_start, vma->vm_page_prot);
    }
    
  3. 物理地址計算:保留起始 = 總內存 - 保留大小 (需對齊頁邊界)。

alloc_bootmem 映射難點補充

若堅持用 alloc_bootmem,獲得線性地址 ptr 後,需在進程上下文中為目標 task_struct 手動建立頁表映射 (參考 ioremap 實現或 vm_insert_page),複雜度極高,不推薦常規驅動開發使用。

總結建議

  • 驅動保留 DMA/共享內存 → 首選 mem= 參數 + ioremap/mmap。
  • 極早期、無驅動介入保留 → 考慮 memblock_reserve (現代內核替代 bootmem) 或設備樹 reserved-memory 節點。
  • 避免在 start_kernel 後期嘗試保留大塊內存,頁面分配器已初始化,碎片化風險大。
Copyright © Windows教程網 All Rights Reserved