2016年1月22日 星期五

核心空間配置記憶體 kmalloc() 和 kfree()


void *kmalloc(size_t size, gfp_t flags)

kmalloc一次最多能申請的記憶體大小由include/Linux/Kmalloc_size.h的內容來決定,
kmalloc一次最多能申請大小為131702B也就是128KB的連續物理記憶體。


flags 的參數如下:

GFP_ATOMIC : 用於interrupt handler 或任何行程外環境的程式..絕不休眠
GFP_KERNEL : 一般核心記憶體配置..有可能休眠
GFP_USER     : 配置記憶體給user-sapce...有可能休眠
GFP_HIGHUSER : 類似 GFP_USER. 但是從高位址區取得空間...
還有一些... 我就沒有打了

高位址區(High memory address) 是一種可供32 bit平台存取大量記憶體的機制...
kmalloc() 能夠配置的記憶體容量是有上限的(因為配置出來的空間是連續的實體記憶體...這樣的空間很少)
,而且上限取決硬體平台與核心組態選項...如果你想維持程式的可移植性...就別期待能夠配置超過128KB的記憶體 ....

核心空間的cache用法如下
kmem_cache_t *kmem_cache_create(name, size, offset, flags)

name : 通常是一串簡短的文字串
offset : 是第一個物件在記憶頁的起始位置....
flag :     
      SLAB_NO_REAP : 保護cache不因系統短缺記憶體而縮減其容量
      SLAB_HWCACHE_ALIGN: 此旗標要求每個資料物件都要對齊一條塊取線....
      SLAB_CACHE_DMA : 要求每一個資料物件都配置在DMA可存取的記憶體

成功建立cache後  妳可以呼叫kmem_cache_alloc為配置cache

void * kmem_cache_alloc(*cache, flags)....

void *vmalloc(unsigned long size).... (v 是virtual的意思)
其作用為在虛擬位址空間(virtual space)配置一段連續的記憶體...
vmalloc() 所得到的每一頁的記憶體...都是個別呼叫alloc_page()所得來的...
在某些場合中,對記憶體區的請求不是很頻繁,較高的記憶體訪問時間也可以接受,
這樣就可以分配一段線性連續,物理不連續的地址,帶來的好處是一次可以分配較大塊的記憶體。
vmalloc對一次能分配的記憶體大小沒有明確限制。出於性能考慮,應謹慎使用vmalloc函數


void * ioremap (unsigned long offset, unsigned long size)
  ioremap是一種更直接的記憶體分配方式,使用時直接指定物理起始地址和需要分配記憶體的大小,
然後將該段物理地址映射到核心地址空間。
ioremap用到的物理地址空間都是事先確定的,和上面的幾種記憶體分配方式並不太一樣。
並不是分配一段新的物理記憶體。
ioremap多用於設備驅動,可以讓CPU直接訪問外部設備的IO空間。
ioremap能映射的記憶體由原有的物理記憶體空間決定,所以沒有進行測試。


get_zero_page(unsigned int flags)
       回傳一個指向新記憶頁的指標...而page的內容全部都是0
__get_free_page(unsigned int flags)
       類似於get_zero_page() , 但是不清除原來的內容
__get_free_page(unsigned int flags,unsigned int order)
      配置一個cross-page的連續記憶體(在實體記憶體上是連續的)...並傳回一個指向記憶體第一個位元組的  
      指標

這裡的flag 理論上和 kmalloc() 所使用的flag相同... 通常以 GFP_KERNEL和 GFP_ATOMIC最為常使用


Reference : Linux 驅動程式第三版
Reference : http://welkinchen.pixnet.net/blog/post/44174948-%E5%B8%B8%E7%94%A8%E6%A0%B8%E5%BF%83%E8%A8%98%E6%86%B6%E9%AB%94%E5%88%86%E9%85%8D%E5%87%BD%E6%95%B8


沒有留言:

張貼留言