天天看點

Linux核心中實作保留記憶體的方法

Linux中保留記憶體(Reserved memory)是指把系統中的一部分記憶體保留起來,核心不會為它建立頁表,一般的應用程式無法通路到這段記憶體。在闆卡調試、記憶體測試和裝置DAM調試的過程中,可以運用這種辦法,先驗證系統在隻有低端記憶體的情況下能否順利啟動;此外,伺服器和存儲系統的環境下,也可以用這種方法從大量系統記憶體中保留出一部分,留給特殊用途使用或者模拟諸如NVDIMM等裝置。是以,有必要對Reserved Memory的使用有一定了解。

1.實作保留記憶體

Linux核心啟動參數cmdline提供了大量的選項,用來設定核心啟動的參數和配置。其中“mem”選項就是用來限制核心可以看到的系統記憶體的大小,是以通過設定

”mem”參數就能實作保留記憶體。當”mem”參數指定的size小于系統實際可用的實體記憶體大小時,實際系統記憶體中出去mem指定的剩下部分就是reserved memory。例如如果某個系統有64G實體記憶體,通過添加mem=48G到kernel command line,就能保留最末尾的(64-48)=16G高端記憶體。

觀察和對比有無mem參數kernel啟動後的/proc/iomem、dmesg的輸出,可以看到64G的實體記憶體映射到CPU位址是0x100000000~0xfffffffff,而48G的高端實體記憶體映射的CPU位址空間位址是:0x100000000~0xbffffffff,是以加上mem=48G後,CPU實體位址0xc00000000~0xFFFFFFFFF對應的從48G到64G的記憶體就給保留了出來。

2.使用保留記憶體

由于核心啟動的時候都沒有為保留記憶體建立頁表,無論是核心提供的kmalloc()還是dma_malloc_coherence()函數,抑或是應用程式的malloc(),realloc()等函數都無法從保留記憶體申請空間。是以為了通路保留記憶體,需要使用某種方法建立起user space address到保留記憶體實體位址的映射。有兩中方法可以實作這種映射:

一、基于某些驅動提供的接口的實作

許多裝置驅動能把自身特有的實體位址空間映射到核心虛拟位址空間,一些SDK軟體包還提供了基于裝置驅動的API接口,來實作使用者态位址和裝置特有實體位址空間的映射。為此,可以參考借鑒這部分代碼實作對保留記憶體的映射。

這種方法的好處是這種映射方式自身能夠實作cache/uncache/write combing/writ thourgh等不同級别的cache一緻性,它的映射方式和所參考的裝置驅動裡指定的屬性一樣。當然,缺點也顯而易見,它使得本來和其他裝置沒有任何關系和瓜葛的reserve memory,使用的時候變得依賴于某種裝置驅動以及對應的SDK庫檔案。

二、基于/dev/mem的實作

衆所周知,Linux核心、驅動的實作時充分考慮了機制和規則相分離的原則。/dev/mem就是核心提供給使用者把一段實體記憶體位址映射到使用者态空間的機制,該機制主要依賴于mmap()系統調用。該系統調用為從指定的起始位址開始、指定長度的一段記憶體建立起頁表,并且映射到目前程式的空閑的使用者态位址空間。

具體的實作可以參考下面的示例代碼:

   char *vmem = NULL;      

  //FILE * fp= fopen("/dev/mem", "w+");       

  int fp = open("/dev/mem", O_RDWR | O_SYNC);       

  if (fp < 0) {         

        printf("Open /dev/mem error!\n");          

        return -1;       

  }       

  vmem =  mmap(NULL, LEN, PROT_READ | PROT_WRITE, MAP_SHARED, fp,                        

       RESERVERD_MEM_START);       

   if (vmem == NULL) {          

     printf("mmap reserver mem on /dev/mem error!\n");          

     return -1;        

    }

這種方法的好處是依賴少,隻在user space開發,調試友善,不足指出是較之上面的方法倚賴于/dev/mem驅動的實作,不能保證映射的記憶體是uncached,而且調用層次深些。

通過以上的分析和比較不難看到,實際開發中最終使用哪一種,需要根據實際的項目要求和資源來選擇。

本文轉自存儲之廚51CTO部落格,原文連結: http://blog.51cto.com/xiamachao/1765570,如需轉載請自行聯系原作者

繼續閱讀