0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

申请函数kmalloc、kzalloc、vmalloc区别说明

Linux内核补给站 来源:Linux内核补给站 作者:Linux内核补给站 2022-05-19 16:13 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

我们都知道在用户空间动态申请内存用的函数是 malloc(),这个函数在各种操作系统上的使用是一致的,对应的用户空间内存释放函数是 free()。注意:动态申请的内存使用完后必须要释放,否则会造成内存泄漏,如果内存泄漏发生在内核空间,则会造成系统崩溃。

那么,在内核空间中如何申请内存呢?一般我们会用到 kmalloc()、kzalloc()、vmalloc() 等,下面我们介绍一下这些函数的使用以及它们之间的区别。

kmalloc()

函数原型:

void *kmalloc(size_t size, gfp_t flags);

kmalloc() 申请的内存位于物理内存映射区域,而且在物理上也是连续的,它们与真实的物理地址只有一个固定的偏移,因为存在较简单的转换关系,所以对申请的内存大小有限制,不能超过128KB。

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

GFP_ATOMIC —— 分配内存的过程是一个原子过程,分配内存的过程不会被(高优先级进程或中断)打断;

GFP_KERNEL —— 正常分配内存;

GFP_DMA —— 给 DMA 控制器分配内存,需要使用该标志(DMA要求分配虚拟地址和物理地址连续)。

flags 的参考用法:

|– 进程上下文,可以睡眠GFP_KERNEL |– 进程上下文,不可以睡眠GFP_ATOMIC ||– 中断处理程序GFP_ATOMIC ||– 软中断GFP_ATOMIC ||– TaskletGFP_ATOMIC |– 用于DMA的内存,可以睡眠GFP_DMA | GFP_KERNEL |– 用于DMA的内存,不可以睡眠GFP_DMA |GFP_ATOMIC

对应的内存释放函数为:

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

kzalloc() 对应的内存释放函数也是 kfree()。

vmalloc()

函数原型:

void *vmalloc(unsigned long size);

vmalloc() 函数则会在虚拟内存空间给出一块连续的内存区,但这片连续的虚拟内存在物理内存中并不一定连续。由于 vmalloc() 没有保证申请到的是连续的物理内存,因此对申请的内存大小没有限制,如果需要申请较大的内存空间就需要用此函数了。

对应的内存释放函数为:

void vfree(const void *addr);

注意:vmalloc() 和 vfree() 可以睡眠,因此不能从中断上下文调用。

总结

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

用于申请内核空间的内存;

内存以字节为单位进行分配;

所分配的内存虚拟地址上连续;

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

kzalloc 是强制清零的 kmalloc 操作;(以下描述不区分 kmalloc 和 kzalloc)

kmalloc 分配的内存大小有限制(128KB),而 vmalloc 没有限制;

kmalloc 可以保证分配的内存物理地址是连续的,但是 vmalloc 不能保证;

kmalloc 分配内存的过程可以是原子过程(使用 GFP_ATOMIC),而 vmalloc 分配内存时则可能产生阻塞;

kmalloc 分配内存的开销小,因此 kmalloc 比 vmalloc 要快;

一般情况下,内存只有在要被 DMA 访问的时候才需要物理上连续,但为了性能上的考虑,内核中一般使用 kmalloc(),而只有在需要获得大块内存时才使用 vmalloc()。例如,当模块被动态加载到内核当中时,就把模块装载到由 vmalloc() 分配的内存上。

审核编辑:符乾江

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 内存
    +关注

    关注

    9

    文章

    3173

    浏览量

    76120
  • 函数
    +关注

    关注

    3

    文章

    4406

    浏览量

    66851
  • malloc
    +关注

    关注

    0

    文章

    53

    浏览量

    346
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    LUA例程-常用的回调函数使用说明

    详细说明LUA脚本函数功能和对应的应用实例。对于LUA脚本编程有很大的帮助和提高技能。
    发表于 11-24 16:43 0次下载

    发布元服务配置隐私说明

    如果检测到元服务中涉及获取敏感隐私权限或者使用受限开放权限,需要填写“应用隐私说明”。 注意 如果软件包中声明使用了受限开放权限,请确保创建的发布Profile也申请了对应权限,否则元服务审核时将会
    发表于 11-24 15:19

    如何为印度服务器申请和配置反向DNS记录?

    恒讯科技为您提供为印度服务器申请和配置反向DNS(rDNS/PTR记录)的完整指南。了解为何反向DNS对邮件送达率、网络安全和服务器信誉至关重要,并遵循我们的分步说明,轻松完成从申请到验证的全过程
    的头像 发表于 10-28 10:12 387次阅读

    ulog_tag_lvl_filter_set()函数无法实现按照文档说明那样实现按模块过滤,怎么解决?

    ulog_tag_lvl_filter_set()函数无法实现按照文档说明那样实现按模块过滤,比如过滤掉所有drv.xxx的日志
    发表于 10-10 07:30

    详解hal_entry入口函数

    当使用RTOS时,程序从main函数开始进行线程调度;当没有使用RTOS时,C语言程序的入口函数main函数调用了hal_entry函数。由于我们新建的工程是没有选用RTOS的,因此,
    的头像 发表于 07-25 15:34 1666次阅读

    MSP430常用内联函数说明

    电子发烧友网站提供《MSP430常用内联函数说明.docx》资料免费下载
    发表于 06-05 17:20 0次下载

    详解RTOS中的Hook函数

    Hook函数是RTOS中的一个关键特性,通过该函数,用户可以增强对任务管理的控制,定义系统行为。
    的头像 发表于 03-24 16:14 841次阅读

    解锁TSMaster fifo函数:报文读取的高效方法

    前言:TSMaster目前有两种读取报文的模式:回调函数模式和fifo模式。fifo函数是TSMaster近期新增的函数,本文将重点介绍fifo模块。关于回调函数的使用方法可以参考帮助
    的头像 发表于 03-14 20:04 947次阅读
    解锁TSMaster fifo<b class='flag-5'>函数</b>:报文读取的高效方法

    STM32H7 ADC_IRQHandler和ADC3_IRQHandler这两个中断入口函数在使用上有什么区别

    STM32H7,ADC_IRQHandler和ADC3_IRQHandler这两个中断入口函数在使用上有何区别
    发表于 03-11 07:28

    充电桩厂家申请CCC认证要准备哪些材料?

    充电桩厂家申请CCC证书需要准备哪些材料?充电桩CCC认证需要提交的资料分为产品技术文件和工厂质量体系文件两大类。以下是全球通检测整理的详细资料清单及说明:一、产品技术文件1.认证申请书(实验室提供
    的头像 发表于 03-10 16:55 752次阅读
    充电桩厂家<b class='flag-5'>申请</b>CCC认证要准备哪些材料?

    AN207 GD32G5x3三角函数加速器TMU的使用说明

    电子发烧友网站提供《AN207 GD32G5x3三角函数加速器TMU的使用说明.pdf》资料免费下载
    发表于 01-21 17:30 2次下载
    AN207 GD32G5x3三角<b class='flag-5'>函数</b>加速器TMU的使用<b class='flag-5'>说明</b>

    西门子TIA Portal中函数FC和函数块FB的相互转换

    描述 本文将介绍在西门子 TIA Portal 中使用 Add-In 插件实现函数 FC 和函数块 FB 的相互转换的方法和步骤。 第1步: 添加 PLC 设备。 选择西门子 CPU 1214C
    的头像 发表于 01-15 10:07 3045次阅读
    西门子TIA Portal中<b class='flag-5'>函数</b>FC和<b class='flag-5'>函数</b>块FB的相互转换

    如何把两个数据返回给调用函数

    已经知道函数会返回两个数据,提前申请两个元素的内存,并且把数组作为参数传递过去,把返回值放在数组中就行。 第三种,定义一个全局的结构体变量,这样可以不用传参也不用返回,直接操作全局数据。 比较典型的错误写法有两种
    的头像 发表于 01-08 10:15 682次阅读

    关联接口函数与libmodbus移植

    可以发现,除了modbus.h包含的接口函数之外,modbus-rtu.h和modbus-tcp.h也包含了必要的接口函数
    的头像 发表于 12-30 15:20 1807次阅读
    关联接口<b class='flag-5'>函数</b>与libmodbus移植

    stdio.h实现了printf函数?

    里面实现了 printf。 实际上并不是,这里就涉及了头文件和库的区别。 头文件一般存放大家都要用的东西,比如函数的声明,结构体的声明,命名新的类型等等。 stdio.h 头文件,里面也只是声明了一下
    的头像 发表于 12-18 10:28 872次阅读