对kmalloc、kzalloc、vmalloc三个内存分配函数的理解

kmalloc、kzalloc、vmalloc都是用于驱动程序中获取指定大小可用内存的函数,我们都知道内核不能直接使用内存地址访问内存。内核运行的地址(虚拟地址)比内存大,某些虚拟地址地址经过映射后对应内存地址,内核运行在虚拟地址状态。这样,对虚拟地址的访问,就变成对与虚拟地址有映射关系的内存地址的访问(物理内存地址)。

对kmalloc、kzalloc、vmalloc的解释参考:https://blog.csdn.net/lu_embedded/article/details/51588902

kmalloc、kzalloc、vmalloc函数原型:

/**
 * kmalloc - allocate memory
 * @size: how many bytes of memory are required.
 * @flags: the type of memory to allocate (see kcalloc).
 *
 * kmalloc is the normal method of allocating memory
 * in the kernel.
 */
static __always_inline void *kmalloc(size_t size, gfp_t flags)
{
	return __kmalloc_node(size, flags, -1);
}

/**
 * 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)
{
	return kmalloc(size, flags | __GFP_ZERO);
}

/*
 *	vmalloc  -  allocate virtually continguos memory
 *
 *	@size:		allocation size
 *
 *	Allocate enough pages to cover @size from the page level
 *	allocator and map them into continguos kernel virtual space.
 *
 *	For tight control over page level allocator and protection flags
 *	use __vmalloc() instead.
 */
void *vmalloc(unsigned long size)
{
       return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL);
}

较常用的 flags(分配内存的方法):

GFP_ATOMIC —— 分配内存的过程是一个原子过程,分配内存的过程不会被(高优先级进程或中断)打断;
GFP_KERNEL —— 正常分配内存;
GFP_DMA —— 给 DMA 控制器分配内存,需要使用该标志(DMA要求分配虚拟地址和物理地址连续)。
flags 的参考用法: 
 |– 进程上下文,可以睡眠     GFP_KERNEL 
 |– 进程上下文,不可以睡眠    GFP_ATOMIC 
 |  |– 中断处理程序       GFP_ATOMIC 
 |  |– 软中断          GFP_ATOMIC 
 |  |– Tasklet         GFP_ATOMIC 
 |– 用于DMA的内存,可以睡眠   GFP_DMA | GFP_KERNEL 
 |– 用于DMA的内存,不可以睡眠  GFP_DMA |GFP_ATOMIC 


注:上下文指的是“开始至结束”之间的过程。

参考上面链接博客的内容:

kmalloc()、kzalloc()、vmalloc() 的共同特点是:

  1. 用于内申请内核空间的存;
  2. 内存以字节为单位进行分配;
  3. 所分配的内存虚拟地址上连续;

kmalloc()、kzalloc()、vmalloc() 的区别是:

  • kzalloc 是强制清零的 kmalloc 操作;(以下描述不区分 kmalloc 和 kzalloc)
  • kmalloc 分配的内存大小有限制(128KB),而 vmalloc 没有限制;
  • kmalloc 可以保证分配的内存物理地址是连续的,但是 vmalloc 不能保证;
  • kmalloc 分配内存的过程可以是原子过程(使用 GFP_ATOMIC),而 vmalloc 分配内存时则可能产生阻塞;
  • kmalloc 分配内存的开销小,因此 kmalloc 比 vmalloc 要快;

总结:

  1. kmalloc用于分配连续的内存地址(物理地址),kzalloc把kmalloc分配的内存地址清零。

  2. vmalloc分配不连续的内存地址,基于这个特点,它可以用于分配大块的不连续的内存空间(物理地址)。

  3. 不论是kmalloc还是vmalloc,他们分配的内存空间(物理地址)对应的虚拟地址都是连续的,内核中访问到的地址都是先虚拟地址,经过页表转换(实际上虚拟地址是通过页表机制与内存形成对应关系的)内存地址。因此,可以使用循环对虚拟地址读取或写入,与分配的内存地址是否联系无关。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值