Chinaunix首页 | 论坛 | 博客
  • 博客访问: 348941
  • 博文数量: 88
  • 博客积分: 907
  • 博客等级: 准尉
  • 技术积分: 1230
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-26 13:27
文章分类

全部博文(88)

文章存档

2017年(1)

2014年(3)

2013年(29)

2012年(21)

2011年(26)

2010年(8)

分类: LINUX

2013-05-16 10:54:45

内核空间:需要包含头文件#include #include #include

1、kmalloc() -- kfree()
申请函数:void *kmalloc(size_t size,int flags);
第一个参数是要分配的块的大小
第二个参数是分配标志。
此函数申请的内存位于物理内存映射区域,而且在物理上也是连续的
它们与真实的物理地址只有一个固定的偏移,存在较简单的转换关系。
释放函数:kfree()
============================================
使用例子:
#include 
#include 
#include
...
unsigned char *kmallocmem;
...
static int xxx_init(void)
{
 unsigned char *p;
 p = "hello dong--";
 kmallocmem = (unsigned char *)kmalloc(100,GFP_KERNEL);
 memset(kmallocmem,0,100);
 memcpy(kmallocmem,p,10);
 printk("kmallocmem = %s\n",kmallocmem);
 ....
 kfree(kmallocmem);
}
================================================

分配标志对应的值:
GFP_KERNEL = 208,最常用的标志,在内核空间的进程中申请内存。
  若暂时不能够满足,则进程会睡眠等待页,即会阻塞。
  因此不能在中断上下文或持有自旋锁的时候使用此标志。
GFP_ATOMIC = 32 若不存在空闲页,则不等待,直接返回。
  在中断处理函数、tasklet和内核定时器等非进程上下文中不能阻塞,
  此时驱动中应该使用此标志来申请内存。
GFP_USER = 131280用来为用户空间分配内存,可能阻塞
GFP_HIGHUSER = 131282类似于GFP_USER,但是从高端内存分配
GFP_NOIO = 16不允许任何IO初始化
GFP_NOFS = 80不允许任何文件系统调用
__GFP_DMA = 1要求分配在能够DMA的内存区
__GFP_HIGHMEM = 2指示分配的内存可以位于高端内存
__GFP_COLD = 256请求一个较长时间不访问的页
__GFP_NOWARN = 512当一个分配无法满足时阻止内核发出警告
__GFP_HIGH = 32高优先级请求,允许获得被内核保留给紧急状况使用的最后的内存页
__GFP_REPEAT = 1024分配失败,则尽力重复尝试
__GFP_NOFAIL = 2048标志只许申请成功,不推荐
__GFP_NORETRY = 4096若申请不到,则立即放弃。

2、__get_free_pages()  free_pages()
   __get_free_page()   free_page()

get_zeroed_page(unsigned int flags)该函数返回一个指向新页的指针并且将该页清零
__get_free_page(unsigned int flags)返回一个指向新页的指针但是该页不清零
__get_free_pages(unsigned int flags,unsigned int order)
    该函数可分配多个页并返回分配内存的首地址
    分配的页数为2^order,分配的页也不清零
    order允许的最大值是10(即1024页)或11(2048页),依赖具体平台。
 如果申请和释放的order不一样,则会引起内存混乱。。。。。
 申请标志与kmalloc()完全一样。
============================================
使用例子:
#include 
#include 
#include
...
unsigned char *pagemem;
...
static int xxx_init(void)
{
 unsigned char *p;
 p = "hello dong--";
 pagemem = (unsigned char *)__get_free_page(0);
 memset(pagemem,0,100);
 memcpy(pagemem,p,10);
 printk("pagemem = %s\n",pagemem);
 ....
 free_page(pagemem);
}
==============================================

3、vmalloc()  --  vfree()
void *vmalloc(unsigned long size);
 一般用在为只存在软件中(没有对应的硬件意义)的较大的顺序缓冲区分配内存
 vmalloc()远大于__get_free_pages()的开销,为了完成vmalloc()需要建立新的页表,
 因此,调用vmalloc来分配少量内存是不妥的。
============================================
使用例子:
#include 
#include 
#include
...
unsigned char *vmallocmem;
...
static int xxx_init(void)
{
 unsigned char *p;
 p = "hello dong--";
 vmallocmem = (unsigned char *)vmalloc(1000000);
 memset(vmallocmem,0,100);
 memcpy(vmallocmem,p,10);
 printk("vmallocmem = %s\n",vmallocmem);
 ....
 vfree(vmallocmem);
}
==============================================

4、slab机制(用于分配大量小对象)
使得在对象前后两次被使用时分配在同一块内存或同一内存空间且保留了基本的数据结构,
可以大大提高效率。
创建slab缓存:
   struct kmem_cache *kmem_cache_create(const char *name,size_t size,
        size_t align,unsigned long flags,
        void (*ctor)(void*,struct kmem_cache *,unsigned long),
        void (*dtor)(void*,struct kmem_cache *,unsigned long));
   用于创建一个slab缓存,它是一个可以驻留任意数目且全部同样大小的后备缓存。
   size是要分配的每个数据结构的大小,
   flags是控制如何进行分配的掩码:SLAB_NO_REAP即使内存紧缺也不自动收缩这块缓存
      SLAB_HWCACHE_ALIGN每个数据对象被对齐到以个缓存
      SLAB_CACHE_DMA要求数据对象在DMA内存区分配
      ...
分配slab缓存:
  void *kmem_cache_alloc(struct kmem_cache *cachep,gfp_t flags)
  上述函数在kmem_cache_create()创建的slab后备缓冲中分配一块并返回首地址指针

释放slab缓存:
  void kmem_cache_free(struct kmem_cache *cachep,void *objp)
  上述函数释放由kmem_cache_alloc()分配的缓存
收回slab缓存:
  int kmem_cache_destroy(struct kmem_cache *cachep)
============================================
使用例子:
#include 
#include 
#include
...
static struct kmem_cache_t *my_cachep;
...
static int xxx_init(void)
{
 unsigned char *p;
 struct my_cachep *ctx;
 p = "hello dong--";
 my_cachep = (unsigned char *)kmem_cache_create("my_cache",sizeof(my_cachep),
      0,SLAB_HWCACHE_ALIGN,NULL);
 ctx = (unsigned char *)kmem_cache_alloc(my_cachep,GFP_KERNEL); 
 memset(ctx,0,100);
 memcpy(ctx,p,10);
 printk("ctx = %s\n",ctx);
 ....
 kmem_cache_free(my_cachep,ctx);
 kmem_cache_destroy(my_cachep);
}
==============================================

5、内存池(类似于slab,也用于分配大量小对象的后备缓存)
创建内存池:
 mempool_t *mempool_create(int min_nr,mempool_alloc_t *alloc_fn,
  mempool_free_t *free_fn,void *pool_data);
 用于创建一个内存池,min_nr参数是需要预分配对象的数目
 alloc_fn和free_fn是指向内存池机制提供的标准对象和分配回收函数的指针
 pool_data是分配和回收函数用到的指针
 gfp_mask是分配标志,只有当__GFP_WAIT标记被指定时,分配函数才会休眠。
分配对象:
 void *mempool_alloc(mempool_t *pool,int gfp_mask);
回收对象:
 void mempool_free(void *element,mempool_t *pool);
回收缓存池:
 void mempool_destroy(mempool_t *pool);

阅读(856) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~