kmalloc使用相關

2021-09-30 12:56:11 字數 2791 閱讀 7649

kmalloc記憶體分配和malloc相似,除非被阻塞否則他執行的速度非常快,而且不對獲得空間清零。

flags引數

#include

void *kmalloc(size_t size, int flags);

第乙個引數size是要分配的塊的大小,第二個引數是分配標誌(flags),他提供了多種kmalloc的行為。

最常用的gfp_kernel,他表示記憶體分配(最終總是呼叫get_free_pages來實現實際的分配,這就是,這就是gfp字首的由來)是代表執行在核心空間的程序執行的。使用gfp_kernel容許kmalloc在分配空閒記憶體時候如果記憶體不足容許把當前程序睡眠以等待。因此這時分配函式必須是可重入的。如果在程序上下文之外如:中斷處理程式、tasklet以及核心定時器中這種情況下,current程序不該睡眠,驅動程式該使用gfp_atomic。

gfp_atomic

用來從中斷處理和程序上下文之外的其他**中分配記憶體. 從不睡眠.

gfp_kernel

核心記憶體的正常分配. 可能睡眠.

gfp_user

用來為使用者空間頁來分配記憶體; 它可能睡眠.

gfp_highuser

如同 gfp_user, 但是從高階記憶體分配, 如果有. 高階內存在下乙個子節描述.

gfp_noio

gfp_nofs

這個標誌功能如同 gfp_kernel, 但是它們增加限制到核心能做的來滿足請求. 乙個 gfp_nofs 分配不允許進行任何檔案系統呼叫, 而 gfp_noio 根本不允許任何 i/o 初始化. 它們主要地用在檔案系統和虛擬記憶體**, 那裡允許乙個分配睡眠, 但是遞迴的檔案系統呼叫會是乙個壞注意.

上面列出的這些分配標誌可以是下列標誌的相或來作為引數, 這些標誌改變這些分配如何進行:

__gfp_dma

這個標誌要求分配在能夠 dma 的記憶體區. 確切的含義是平台依賴的並且在下面章節來解釋.

__gfp_highmem

這個標誌指示分配的記憶體可以位於高階記憶體.

__gfp_cold

正常地, 記憶體分配器盡力返回"緩衝熱"的頁 -- 可能在處理器緩衝中找到的頁. 相反, 這個標誌請求乙個"冷"頁, 它在一段時間沒被使用. 它對分配頁作 dma 讀是有用的, 此時在處理器緩衝**現是無用的. 乙個完整的對如何分配 dma 快取的討論看"直接記憶體訪問"一節在第 1 章.

__gfp_nowarn

這個很少用到的標誌阻止核心來發出警告(使用 printk ), 當乙個分配無法滿足.

__gfp_high

這個標誌標識了乙個高優先順序請求, 它被允許來消耗甚至被核心保留給緊急狀況的最後的記憶體頁.

__gfp_repeat

__gfp_nofail

__gfp_noretry

這些標誌修改分配器如何動作, 當它有困難滿足乙個分配. __gfp_repeat 意思是" 更盡力些嘗試" 通過重複嘗試 -- 但是分配可能仍然失敗. __gfp_nofail 標誌告訴分配器不要失敗; 它盡最大努力來滿足要求. 使用 __gfp_nofail 是強烈不推薦的; 可能從不會有有效的理由在乙個裝置驅動中使用它. 最後, __gfp_noretry 告知分配器立即放棄如果得不到請求的記憶體.

2.記憶體區段

__gfp_dma和__gfp_highmem的使用與平台相關,linux把記憶體分成3個區段:可用於dma的記憶體、常規記憶體、以及高階記憶體。x86平台上isa裝置dma區段是記憶體的前16mb,而pci裝置無此限制。

記憶體區後面的機制在 mm/page_alloc.c 中實現, 而記憶體區的初始化在平台特定的檔案中, 常常在 arch 目錄樹的 mm/init.c。

linux 處理記憶體分配通過建立一套固定大小的記憶體物件池. 分配請求被這樣來處理, 進入乙個持有足夠大的物件的池子並且將整個記憶體塊遞交給請求者.驅動開發者應當記住的一件事情是, 核心只能分配某些預定義的, 固定大小的位元組陣列.

如果你請求乙個任意數量記憶體, 你可能得到稍微多於你請求的, 至多是 2 倍數量.同樣, 程式設計師應當記住 kmalloc 能夠處理的最小分配是 32 或者 64 位元組, 依賴系統的體系所使用的頁大小. kmalloc 能夠分配的記憶體塊的大小有乙個上限.這個限制隨著體系和核心配置選項而變化. 如果你的**是要完全可移植, 它不能指望可以分配任何大於 128 kb. 如果你需要多於幾個 kb, 但是, 有個比 kmalloc 更好的方法來獲得記憶體

在裝置驅動程式或者核心模組中動態開闢記憶體,不是用malloc,而是kmalloc ,vmalloc,或者用get_free_pages直接申請頁。釋放記憶體用的是kfree,vfree,或free_pages。kmalloc函式返回的是虛擬位址(線性位址). kmalloc特殊之處在於它分配的記憶體是物理上連續的,這對於要進行dma的裝置十分重要. 而用vmalloc分配的記憶體只是線性位址連續,實體地址不一定連續,不能直接用於dma.

注意kmalloc最大只能開闢128k-16,16個位元組是被頁描述符結構占用了。kmalloc用法參見khg.

記憶體對映的i/o口,暫存器或者是硬體裝置的ram(如視訊記憶體)一般占用f0000000以上的位址空間。在驅動程式中不能直接訪問,要通過kernel函式vremap獲得重新對映以後的位址。

另外,很多硬體需要一塊比較大的連續記憶體用作dma傳送。這塊記憶體需要一直駐留在記憶體,不能被交換到檔案中去。但是kmalloc最多只能開闢大小為32 x page_size的記憶體,一般的page_size=4kb,也就是128kb的大小的記憶體。

記憶體分配 kmalloc

kmalloc 記憶體分配引擎是乙個功能強大的工具,下面我們來講解一下這個函式。kmalloc 函式分配記憶體時有幾個特點 1 獲取記憶體空間時不會對記憶體空間進行清零,也就是說,分配給它的區域仍然保持著原有的資料。2 它分配的區域在物理記憶體中也是連續的。3 kmalloc最常用的標誌是gfp k...

kmalloc分配核心堆空間

kmalloc函式的原型是 include void kmalloc size t size,int flags kmalloc函式說明 size是要分配的塊大小 flags分配方式,控制kmalloc分配記憶體的方式 在沒有阻塞的情況下,分配記憶體快,並且對於分配到的記憶體塊,不對該記憶體塊清零,...

kzalloc和kmalloc函式詳解

用kzalloc申請記憶體的時候,效果等同於先是用 kmalloc 申請空間 然後用 memset 來初始化 所有申請的元素都被初始化為 0.view plain kzalloc allocate memory.the memory is set to zero.size how many byte...