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

2021-10-01 06:01:54 字數 2059 閱讀 7639

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,而且呼叫層次深些。

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

Linux核心中的記憶體屏障

編譯器有時會對 做一些優化,例如嘗試在保證程式執行正確的前提下修改指令順序或優化ldr str指令,讓程式執行地更快。但是編譯器畢竟不能完全猜透人的心思,有時候它做的優化會導致程式執行不符我們的預期。因此,核心中提供了一些額外的函式,可以插在某段 裡,告訴編譯器不要在這裡做指令優化。這些函式分為兩種...

Linux核心中記憶體分配函式

1.原理說明 linux核心中採 用了一種同時適用於32位和64位系統的內 存分頁模型,對於32位系統來說,兩級頁表足夠用了,而在x86 64系 統中,用到了四級頁表,如圖2 1所示。四級頁表分別為 頁全域性目錄 page global directory 頁上級目錄 page upper dire...

linux核心中沒有分頁記憶體

linux核心中沒有分頁記憶體嗎?是的,沒有,那麼windows的核心為何就有呢?畢竟不是乙個家族不好做全方位的評判,我的結論就是linux上的任何的程式只將核心作為乙個平台而不依賴核心。這個事實的結果就是在linux核心中不能分配過大的記憶體,linux核心中唯一可以分配大記憶體的地方就是vmal...