linux内核空间内存动态申请

参考:《linux设备驱动开发详解》华清远见 ,--人民邮电出版社

用户空间内存动态申请

在用户空间动态申请内存的函数为 malloc(),这个函数在各种操作系统上的使用是一致的,malloc()申请的内存的释放函数为 free()。malloc()的内存一定要被 free(),否则会造成内存泄漏。理想情况下,malloc()和 free()应成对出现,即谁申请,就由谁释放。

void *malloc(unsigned int num_bytes);  /* 函数原型 */
void free(void *ptr);
char *func(void)
{
    char *p;
    p = malloc(...);
    if(p == NULL)
    {
        ...
    }
    free(p);
}

内核空间动态申请内存

问题:

  • 有哪些函数可以动态申请内存?
  • 这些动态申请内存函数之间有什么区别?

在 Linux 内核空间申请内存涉及的函数主要包括 kmalloc()、_ _get_free_pages()和vmalloc()等。kmalloc()和_ _get_free_pages()(及其类似函数)申请的内存位于物理内存映射区域,而且在物理上也是连续的,它们与真实的物理地址只有一个固定的偏移,因此存在较简单的转换关系。而 vmalloc()在虚拟内存空间给出一块连续的内存区,实质上,这片连续的虚拟内存在物理内存中不一定连续,而 vmalloc()申请的虚拟内存和物理内存之间也没有简单的换算关系。

1.kmalloc()

void *kmalloc(size_t size, gfp_t flags);

参数:

  1. 分配的块的大小
  2. 分配标志,用于控制kmalloc的行为,一般为GFP_KERNEL,代表优先权。

kmalloc()的底层依赖_ _get_free_pages()实现,分配标志的前缀 GFP 正好是这个底层函数的缩写。使用 GFP_ KERNEL 标志申请内存时,若暂时不能满足,则进程会睡眠等待页,即会引起阻塞,因此不能在中断上下文或持有自旋锁的时候使GFP_KERNE 申请内存。

gfp_mask标志:1.行为修饰符 2.区修饰符 3.类型 一一《linux内核设计与实现——第三版——中文版》P192

进行上下文,可以睡眠

GFP_KERNEL
进行上下文,不可以睡眠GFP_ATOMIC
中断处理程序GFP_ATOMIC
软中断GFP_ATOMIC
taskletGFP_ATOMIC
需要用于DMA的内存,可以睡眠(GFP_DMA|GFP_KERNEL)
需要用于DMA的内存,不可以睡眠(GFP_DMA|GFP_ATOMIC)

2.__get_free_pages ()

_ _get_free_pages()系列函数/宏是 kmalloc()实现的基础,_ _get_free_pages()系列函数/宏包括 get_zeroed_page()、__get_free_page()和_ _get_free_pages()。

get_zeroed_page(unsigned int flags); //该函数返回一个指向新页的指针并且将该页清零。
__get_free_page(unsigned int flags); //该宏返回一个指向新页的指针但是该页不清零,它实际上为:
#define __get_free_page(gfp_mask) \
__get_free_pages((gfp_mask),0)  //就是调用了下面的
__get_free_pages()   //申请 1 页。
__get_free_pages(unsigned int flags, unsigned int order); 
/*该函数可分配多个页并返回分配内存的首地址,分配的页数为 2order,分配的页也不清零。order 允许的最大值是 10(即 1024 页)或者 11(即2048 页),依赖于具体的硬件平台。*/

使用_ _get_free_pages()系列函数/宏申请的内存应使用下列函数释放:
 

void free_page(unsigned long addr);
void free_pages(unsigned long addr, unsigned long order);

3.vmalloc()

vmalloc()一般用在为只存在于软件中(没有对应的硬件意义)的较大的顺序缓冲区分配内存,vmalloc()远大于__get_free_pages()的开销,为了完成 vmalloc(),新的页表需要被建立。因此,只是调用 vmalloc()来分配少量的内存(如 1 页)是不妥的。
vmalloc()申请的内存应使用 vfree()释放,vmalloc()和 vfree()的函数原型如下:
 

void *vmalloc(unsigned long size);
void vfree(void * addr);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值