linux中kmalloc()與vmalloc()

    琢磨了很久也參考了很多資料,發現很多都說的有點含糊,在這裏先介紹一下Linux中對實際內存的一個分配,Linux內核將實際內存(注意是實際內存,這裏暫且考慮不大於1G的內存)分爲三個區段:可用於DMA的內存、常規內存以及高端內存。這裏只介紹一下高端內存與地段內存。

       高端內存是指物理地址大於 896M 的內存。對於這樣的內存,無法在“內核直接映射空間”進行映射。並沒有和內核地址空間建立一一對應的關係(即虛擬地址=物理地址+PAGE_OFFSET這樣的關係),所以不能使用get_free_pages()這樣的頁分配器進行內存的分配,而必須使用alloc_pages()這樣的夥伴系統算法的接口得到struct *page結構,然後將其映射到內核地址空間,注意這個時候映射後的地址並非和物理地址相差PAGE_OFFSET.

   

     再來看看kmalloc(),kmalloc‍()是內核中最常見的內存分配方式,它最終調用夥伴系統的__get_free_pages()函數分配,(也就是說,對於分配高端內存來說,不能用kmalloc函數來進行分配)。根據傳遞給這個函數的flags參數,決定這個函數的分配適合什麼場合,如果標誌是GFP_KERNEL則僅僅可以用於進程上下文中,如果標誌GFP_ATOMIC則可以用於中斷上下文或者持有鎖的代碼段中。

kmalloc返回的線形地址是直接映射的,而且用連續物理頁滿足分配請求,且內置了最大請求數(2**5=32頁)。

     再來看看vmalloc()。vmalloc()函數爲了把物理上不連續的頁面轉換爲虛擬地址空間上連續的頁,必須專門建立頁表項。還有,通過vmalloc()獲得的頁必須一個一個的進行映射(因爲它們物理上不是連續的),這就會導致比直接內存映射大得多的緩衝區刷新。因爲這些原因,vmalloc()僅在絕對必要時纔會使用——典型的就是爲了獲得大塊內存時,例如,當模塊被動態插入到內核中時,就把模塊裝載到由vmalloc()分配的內存上。

     總結一下:kmalloc()與kfree()對應,可以分配連續的物理內存

vmalloc()與vfree()對應,可以分配連續的虛擬內存,但是物理內存不一定連續,適用於分配大量內存

vmalloc()函數用起來比較簡單:

char *buf;

buf = vmalloc16*PAGE_SIZE; /*獲得16*/

if!buf

   /*錯誤!不能分配內存*/

在使用完分配的內存之後,一定要釋放它:

vfreebuf);

 

發佈了56 篇原創文章 · 獲贊 19 · 訪問量 28萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章