前言
我們都知道在使用者空間申請記憶體的函式是malloc()
,這個函式在各個作業系統上的使用是一致的,對應的使用者空間的記憶體釋放韓式是free()
,那麼在核心空間中記憶體如何申請呢?
一般我們會用到kmalloc(),kzalloc(), vmalloc(), alloc_page()
等,下面我們來詳細看一下他們的各個引數以及他們的區別
kmalloc
函式原型
void *kmalloc(size_t size, gfp_t flags);
kamlloc申請的記憶體區域位於物理記憶體的對映區域,而且在物理上也是連續的,它們與真實的實體地址只有乙個固定的偏移,存在比較簡單的轉換關係,所以對申請的記憶體大小有限制,不能超過128kb。
比較常用的幾個flags
對應的記憶體釋放函式
void kfree(const void*objp);
kzalloc()
kzalloc() 函式與 kmalloc() 非常相似,引數及返回值是一樣的,可以說是前者是後者的乙個變種,因為 kzalloc() 實際上只是額外附加了 __gfp_zero 標誌。所以它除了申請核心記憶體外,還會對申請到的記憶體內容清零。
/**
* kzalloc - allocate memory. the memory is set to zero.
*@size: how many bytes of memory are required.
*@flags: the type of memory to allocate (see kmalloc).
* */
static inline void *kzalloc(size_t size, gfp_t flags)
kzalloc() 對應的記憶體釋放函式也是 kfree()。
vmalloc()
函式原型
void *vmalloc(unsigned long size);
vmalloc() 函式則會在虛擬記憶體空間給出一塊連續的記憶體區,但這片連續的虛擬記憶體在物理記憶體中並不一定連續。由於 vmalloc() 沒***申請到的是連續的物理記憶體,因此對申請的記憶體大小沒有限制,如果需要申請較大的記憶體空間就需要用此函式了。
對應的記憶體釋放函式為:
void vfree(const void *addr);
注意:vmalloc() 和 vfree() 可以睡眠,因此不能從中斷上下文呼叫。
alloc_page()
alloc_page()用於申請連續的物理頁,可以通過page_address()把指定的頁轉化成邏輯位址。
總結kmalloc()、kzalloc()、vmalloc() 的共同特點是:
kzalloc 是強制清零的 kmalloc 操作;(以下描述不區分 kmalloc 和 kzalloc)
kmalloc 分配的記憶體大小有限制(128kb),而 vmalloc 沒有限制;
kmalloc 可以保證分配的記憶體實體地址是連續的,但是 vmalloc 不能保證;
kmalloc 分配記憶體的過程可以是原子過程(使用 gfp_atomic),而 vmalloc 分配記憶體時則可能產生阻塞;
kmalloc 分配記憶體的開銷小,因此 kmalloc 比 vmalloc 要快;
一般情況下,記憶體只有在要被 dma 訪問的時候才需要物理上連續,但為了效能上的考慮,核心中一般使用 kmalloc(),而只有在需要獲得大塊記憶體時才使用 vmalloc()。例如,當模組被動態載入到核心當中時,就把模組裝載到由 vmalloc() 分配的記憶體上。
Linux核心下記憶體空間的申請
2020 05 23 關鍵字 kmalloc kzalloc kcalloc kmalloc 是linux核心開發中最常使用的申請記憶體的函式。它的原型如下所示 include void kmalloc size t size,int flags 函式的返回值通常就指向所申請到的記憶體空間的起始位址...
Linux驅動 使用者空間,核心空間記憶體互動測試
linux驅動 使用者空間,核心空間記憶體互動測試 環境 主機 fedora12 目標板 mini6410 目標板linux核心版本 2.6.38 實現功能 使用read函式讀取核心空間開闢的陣列,使用write函式從使用者空間寫入資料到核心空間開闢的陣列 說明 linux中核心空間和使用者空間有不...
Linux記憶體 核心位址空間
一,為什麼需要高階記憶體 答 對於32位機器,linux虛擬記憶體最大為4g,其中3 4g空間是用作核心空間,考慮到如果物理記憶體大於1g,那麼物理記憶體不能得到完全的對映,因此,linux 規定 核心直接對映空間 最多對映 896m 物理記憶體,arm體系架構上有高階記憶體的概念,不過不是固定在8...