美文网首页linux内核-ttm
内核中申请内存的函数

内核中申请内存的函数

作者: Joe_HUST | 来源:发表于2017-09-27 00:08 被阅读0次

Linux内核空间中常见的内存分配函数

1

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
 |  |– Tasklet         GFP_ATOMIC
 |– 用于DMA的内存,可以睡眠   GFP_DMA | GFP_KERNEL
 |– 用于DMA的内存,不可以睡眠  GFP_DMA |GFP_ATOMIC
释放内存
void kfree(const void *objp)

2

kzalloc() 函数与 kmalloc() 非常相似,参数及返回值是一样的,可以说是前者是后者的一个变种,因为 kzalloc() 实际上只是额外附加了 __GFP_ZERO 标志。所以它除了申请内核内存外,还会对申请到的内存内容清零。kzalloc() 对应的内存释放函数也是 kfree()。
static inline void *kzalloc(size_t size,gfp_t flags) {return kmalloc(size,flags |_GFP_ZERO);}

3

void *vmalloc(unsigned long size);vmalloc() 函数则会在虚拟内存空间给出一块连续的内存区,但这片连续的虚拟内存在物理内存中并不一定连续。由于 vmalloc() 没有保证申请到的是连续的物理内存,因此对申请的内存大小没有限制,如果需要申请较大的内存空间就需要用此函数了。
释放内存
void vfree(const void *addr);
注意vmalloc和vfree时可以睡眠的,因此不能从中断上下问调用

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

  • kzalloc 是强制清零的 kmalloc 操作;(以下描述不区分 kmalloc 和 kzalloc)
  • kmalloc 分配的内存大小有限制(128KB),而 vmalloc 没有限制;
  • kmalloc 可以保证分配的内存物理地址是连续的,但是 vmalloc 不能保证;
  • kmalloc 分配内存的过程可以是原子过程(使用 GFP_ATOMIC),而 vmalloc 分配内存时则可能产生阻塞;
  • kmalloc 分配内存的开销小,因此 kmalloc 比 vmalloc 要快;
    一般情况下,内存只有在要被 DMA 访问的时候才需要物理上连续,但为了性能上的考虑,内核中一般使用 kmalloc(),而只有在需要获得大块内存时才使用 vmalloc()。例如,当模块被动态加载到内核当中时,就把模块装载到由 vmalloc() 分配的内存上。

Linux 内核空间和用户空间数据交换的方式

一般地,在使用虚拟内存技术的多任务系统上,内核和应用有不同的地址空间,因此,在内核和应用之间以及在应用与应用之间进行数据交换需要专门的机制来实现,众所周知,进程间通信(IPC)机制就是为实现应用与应用之间的数据交换而专门实现的。

  • Linux内核提供了多个函数和宏用于内核空间和用户空间传递数据。 主要有:access_ok(),copy_to_user(),copy_from_user,put_user,get_user。

通常情况下,应用程序通过内核接口访问驱动程序,因此,驱动程序需要和应用程序交换数据。Linux将存储器分为“内核空间”和“用户空间”。操作系统和驱动程序在内核空间运行,应用程序在用户空间运行,两者不能简单地使用指针传递数据。因为Linux系统使用了虚拟内存机制,用户空间的内存可能被换出,当内核空间使用用户空间指针时,对应的数据可能不在内存中。Linux内核提供了多个函数和宏用于内核空间和用户空间传递数据。

相关文章

  • 内核中申请内存的函数

    Linux内核空间中常见的内存分配函数 1 void *kmalloc(size_t size,gfp_t fla...

  • 嵌入式Linux驱动题

    嵌入式Linux驱动题 linux内核里面,内存申请有哪几个函数? kmalloc() __get_free_...

  • 内核态

    首先,内核函数在内存中,大家都知道内核态是调用内核的函数,因为用户空间所在等级低,那是如何来陷入内核态呢,内核态的...

  • 5.动态内存分配

    内存申请 动态申请的内存可以跨函数使用 内存影像 练习

  • 内核内存管理接口简述

    最近项目需要,一直在看内核方面的问题,典型的就是内存管理。 我们都知道在用户空间动态申请内存用的函数是 mallo...

  • [C++之旅] 6 内存的申请和释放

    [C++之旅] 6 内存的申请和释放 申请内存的方式 C语言方式 申请内存使用函数void *malloc(siz...

  • OC内存布局

    一、 内存布及优化 1.1、内存布局及存储类型 内存区说明内核区内核占用的内存区域栈区存放函数的参数值、局部变量的...

  • 5 DirectByteBuffer内存释放

    我们已经知道,在网络编程中,为了避免频繁的在用户空间与内核空间拷贝数据,通常会直接从内核空间中申请内存,存放数据,...

  • 数组

    一. 栈和堆 栈:当一个函数调用时,会在栈内存中申请一个空间,当函数中定义一个变量时,会分配到这个函数申请的栈空间...

  • c++学习笔记——第二天

    1、c++中的内存管理 C语言提供了malloc和free两个函数(库函数)实现,完成对内存的释放和申请,而c++...

网友评论

    本文标题:内核中申请内存的函数

    本文链接:https://www.haomeiwen.com/subject/cbfyextx.html