在做驅動開發時,經常會使用到的kmalloc函數進行內存的分配,下面對kmalloc在內核上的語言集進行相關的解釋。
一、kmalloc 函數的原型:
#include <linux/slab.h>
void *kmalloc(size_t size, int flags);
參數:
kmalloc 的第一個參數是要分配的塊的大小,第二個參數是分配標志。
size 參數:
用戶空間malloc 是基於堆內存分配,內核負責管理系統物理內存,物理內存只能按頁面進行分配,因此,kmalloc是基於頁進行分配。另外需要注意的一點是內核只能分配一些預定義的、固定 大小的字節數組。kmalloc 可以處理的最小的內存塊是32或64,最大分配的內存大小為128K。
flags參數:
GFP_KERNEL
內核內存的通常分配方法,可能會引起休眠。
GFP_USER
用於為用戶空間分配內存,可能會休眠。
GFP_ATOMIC
用於在中斷處理例程或其他運行於進程上下文之外的代碼中分配內存,不會休眠。
GFP_HIGHUSER
用於為用戶空間分配內存,指高端內存分配,可能會休眠。
GFP_NOIO
禁止任何I/O的初始化(主要在虛擬內存代碼中使用)。
GFP_NOFS
分配不允許執行任何文件系統調用(主要在文件系統代碼中使用)。
****************************************************************
分割線以上的flag可以和分割線以下的flag “或”起來使用
****************************************************************
__GFP_DMA
該標志請求分配發生在可進行DMA的內存區段中。
__GFP_HIGHMEM
該標志表明要分配的內存可位於高端內存。
__GFP_NOWAPN
該標志使用的次數較少,它主要是避免內核在無法滿足分配請求時產生警告信息。
__GFP_COLD
該標志表示請求尚未使用的“冷”頁面。
__GFP_HIGH
該標記標記了一個高優先級的請求,它允許為緊急狀況而消耗由內核保留的最后一些頁面。
__GFP_REPEAT
該標志表示在分配器在滿足分配請求而遇到困難時,“努力再嘗試一次”,它會重新嘗試分配,但還是有失敗的可能性。
__GFP_NOFAIL
該標志表示在分配器在滿足分配請求而遇到困難時告訴分配器始終不返回失敗。
__GFP_NORETRY
該標志表示再請求內存不可獲得的時候會立即返回。
GFP_前綴是由於在分配內存時總是調用get_free_page來實現實際的分配而得來的縮寫。
二、關於的get_free_page 和相關函數有以下:
get_zeroed_page(unsigned int flags);
返回指向新頁面的指針,並將頁面清零。
__get_free_page(unsigned int flags);
與 get_zeroed_page(unsigned int flags)類似,但是不清零頁面。
__get_free_pages(unsigned int flags, unsigned int order);
分配若干(物理連續)頁面,並且返回指向該區域第一個字節的指針,但是對於頁面不進行清零。
當程序不需要使用頁面時,可以使用以下兩個函數中的一個進行的釋放,第一個函數是宏,展開后是對第二個函數的調用:
void free_page(unsigned long addr);
void free_pages(unsigned long addr, unsigned long order);
以上就是我個人認為kmalloc一些有用信息的提取,至於關於頁的詳細說明,以后給大家分享。
歡迎大家進行補充交流。