`
sony-soft
  • 浏览: 1008267 次
文章分类
社区版块
存档分类
最新评论

kmalloc/kfree,vmalloc/vfree函数用法和区别

 
阅读更多

kmalloc/kfree,vmalloc/vfree函数用法和区别

1.kmalloc

1>kmalloc内存分配和malloc相似,除非被阻塞否则他执行的速度非常快,而且不对获得空间清零.

<

tiger说明:在用kmalloc申请函数后,要对起清零

memset()函数对申请的内存进行清零。

>

2>kamlloc函数原型:

#include<linux/slab.h>

Void *kmalloc(size_t size, int flags);

(1)第一个参数是要分配的块的大小

(2)第二个参数是分配标志(flags),他提供了多种kmalloc的行为。

(3)第三个最常用的GFP_KERNEL

A.表示内存分配(最终总是调用get_free_pages来实现实际的分配;这就是GFP前缀的由来)是代表运行在内核空间的进程执行的。使用GFP_KERNEL容许kmalloc在分配空闲内存时候如果内存不足容许把当前进程睡眠以等待。因此这时分配函数必须是可重入的。如果在进程上下文之外如:中断处理程序、tasklet以及内核定时器中这种情况下current进程不该睡眠,驱动程序该使用GFP_ATOMIC.

B.GFP_ATOMIC

用来从中断处理和进程上下文之外的其他代码中分配内存. 从不睡眠.

C.GFP_KERNEL

内核内存的正常分配. 可能睡眠.

D.GFP_USER

用来为用户空间页来分配内存; 它可能睡眠.

E.GFP_HIGHUSER

如同 GFP_USER, 但是从高端内存分配, 如果有. 高端内存在下一个子节描述.

F.GFP_NOFS,GFP_NOIO

这个标志功能如同 GFP_KERNEL, 但是它们增加限制到内核能做的来满足请求. 一个 GFP_NOFS 分配不允许进行任何文件系统调用, GFP_NOIO 根本不允许任何 I/O 初始化. 它们主要地用在文件系统和虚拟内存代码, 那里允许一个分配睡眠, 但是递归的文件系统调用会是一个坏注意.

上面列出的这些分配标志可以是下列标志的相或来作为参数, 这些标志改变这些分配如何进行:

__GFP_DMA

这个标志要求分配在能够 DMA 的内存区. 确切的含义是平台依赖的并且在下面章节来解释.

__GFP_HIGHMEM

这个标志指示分配的内存可以位于高端内存.

__GFP_COLD

正常地, 内存分配器尽力返回"缓冲热"的页 -- 可能在处理器缓冲中找到的页. 相反, 这个标志请求一个"", 它在一段时间没被使用. 它对分配页作 DMA 读是有用的, 此时在处理器缓冲中出现是无用的. 一个完整的对如何分配 DMA 缓存的讨论看"直接内存存取"一节在第 1 .

__GFP_NOWARN

这个很少用到的标志阻止内核来发出警告(使用 printk ), 当一个分配无法满足.

__GFP_HIGH

这个标志标识了一个高优先级请求, 它被允许来消耗甚至被内核保留给紧急状况的最后的内存页.

Ø __GFP_REPEAT

__GFP_NOFAIL

__GFP_NORETRY

这些标志修改分配器如何动作, 当它有困难满足一个分配. __GFP_REPEAT 意思是" 更尽力些尝试" 通过重复尝试 -- 但是分配可能仍然失败. __GFP_NOFAIL 标志告诉分配器不要失败; 它尽最大努力来满足要求. 使用 __GFP_NOFAIL 是强烈不推荐的; 可能从不会有有效的理由在一个设备驱动中使用它. 最后, __GFP_NORETRY 告知分配器立即放弃如果得不到请求的内存.

Ø 内存区段

__GFP_DMA__GFP_HIGHMEM的使用与平台相关,Linux把内存分成3个区段:可用于DMA的内存、常规内存、以及高端内存。X86平台上ISA设备DMA区段是内存的前16MB,而PCI设备无此限制。

内存区后面的机制在 mm/page_alloc.c 中实现, 而内存区的初始化在平台特定的文件中, 常常在 arch 目录树的 mm/init.c

3>kamlloc的使用方法:

Linux 处理内存分配通过创建一套固定大小的内存对象池. 分配请求被这样来处理, 进入一个持有足够大的对象的池子并且将整个内存块递交给请求者. 驱动开发者应当记住的一件事情是, 内核只能分配某些预定义的, 固定大小的字节数组.

如果你请求一个任意数量内存, 你可能得到稍微多于你请求的, 至多是 2 倍数量. 同样, 程序员应当记住 kmalloc 能够处理的最小分配是 32 或者 64 字节, 依赖系统的体系所使用的页大小. kmalloc 能够分配的内存块的大小有一个上限. 这个限制随着体系和内核配置选项而变化. 如果你的代码是要完全可移植, 它不能指望可以分配任何大于 128 KB. 如果你需要多于几个 KB, 但是, 有个比 kmalloc 更好的方法来获得内存。在设备驱动程序或者内核模块中动态开辟内存,不是用malloc,而是kmalloc ,vmalloc,或者用get_free_pages直接申请页释放内存用的是kfree,vfree,或free_pages. kmalloc函数返回的是虚拟地址(线性地址). kmalloc特殊之处在于它分配的内存是物理上连续的,这对于要进行DMA的设备十分重要. 而用vmalloc分配的内存只是线性地址连续,物理地址不一定连续,不能直接用于DMA.

  注意kmalloc最大只能开辟128k-1616个字节是被页描述符结构占用了。kmalloc用法参见khg.

  内存映射的I/O口,寄存器或者是硬件设备的RAM(如显存)一般占用F0000000以上的地址空间。在驱动程序中不能直接访问,要通过kernel函数vremap获得重新映射以后的地址。

  另外,很多硬件需要一块比较大的连续内存用作DMA传送。这块内存需要一直驻留在内存,不能被交换到文件中去。但是kmalloc最多只能开辟大小为32XPAGE_SIZE的内存,一般的PAGE_SIZE=4kB,也就是128kB的大小的内存。

3.kmallocvmalloc的区别

vmalloc() kmalloc()都可用于分配内存

kmalloc()分配的内存处于3GB~high_memory ,这段内核空间与物理内存的映射一一对应

vmalloc()分配的内存在 VMALLOC_START~4GB之间,这段非连续内 存区映射到物理内存也可能是非连续的

在内核空间中调用kmalloc()分配连续物理空间,而调用vmalloc()分配非物理连续空间。

kmalloc()所分配内核空间中的地址称为内核逻辑地址

vmalloc()分配的内核空间中的地址称 为内核虚拟地址

vmalloc()在分配过程中须更新内核页表

总结:

1.kmallocvmalloc分配的是内核的内存,malloc分配的是用户的内存

2.kmalloc保证分配的内存在物理上是连续的, kmalloc()分配的内存在0xBFFFFFFF0xFFFFFFFF以上的内存中,driver一般是用它来完成对DS的分配,更适合于类似设备驱动的程序来使用;

3.vmalloc保证的是在虚拟地址空间上的连续,vmalloc()则是位于物理地址非连续,虚地址连续区,起始位置由VMALLOL_START来决定,一般作为交换区、模块的分配。

3.kmalloc能分配的大小有限,vmallocmalloc能分配的大小相对较大(因为vmalloc还可以处理交换空间)。

4.内存只有在要被DMA访问的时候才需要物理上连续,vmallockmalloc要慢

5.vmalloc使用的正确场合是分配一大块,连续的,只在软件中存在的,用于缓冲的内存区域。不能在微处理器之外使用。

6.vmalloc 中调用了 kmalloc GFPKERNEL),因此也不能应用于原子上下文。

7.kmalloc kfree管理内核段内分配的内存,这是真实地址已知的实际物理内存块。

8.vmalloc对应于vfree,分配连续的虚拟内存,但是物理上不一定连续。

9.kmalloc分配内存是基于slab,因此slab的一些特性包括着色,对齐等都具备,性能较好。物理地址和逻辑地址都是连续的

分享到:
评论

相关推荐

    kmalloc/kfree封装代码

    kmalloc/kfree内存管理函数封装代码。

    kmalloc()和vmalloc()的区别

    kmalloc()和vmalloc()的区别

    Linux内存管理之malloc、vmalloc、kmalloc

    Linux内存管理之malloc、vmalloc、kmalloc, 区别,相似之处

    memory_map_kmalloc.c

    vmalloc分配的内存虚拟地址连续但物理地址不连续,所以只能在缺页异常中逐页建立映射 下面给出使用kmalloc分配内存,并在mmap函数中一次性建立映射的示例

    linux c内存分配函数介绍

    介绍linux c中的基本内存分配函数, 比如malloc, kmalloc, zalloc等等

    Kmalloc 共享内存池技术架构详解-KaiwuDB

    本期内容主题为《 Kmalloc 共享内存池技术架构详解》,KaiwuDB 为优化内存池技术,将内存池分为多个 Heap,每个 Heap 使用不同的数据结构管理内存,在申请和释放内存时,允许多个进程访问同一块内存,使用并发访问...

    BianOS:一个应用从OS开发中学到的东西的项目

    创建kmalloc和kfree 编写更好的文档,最近的更改 改善Bochs支持 建筑 构建BianOS非常简单,设置依赖关系并执行单个命令。 依存关系 必需的 gcc:构建和编译c文件 genisoimage / mkisofs:生成iso图像 ld:将所有...

    LINUX设备驱动第三版_588及代码.rar

    vmalloc及其辅助函数 per-CPU变量 获取大的缓冲区 快速参考 第九章 与硬件通信 I/O端口和I/O内存 使用I/O端口 I/O端口示例 使用I/O内存 快速参考 第十章 中断处理 准备并口 安装中断处理例程 实现中断...

    Linux DeviceDrivers 3rd Edition

    vmalloc及其辅助函数 225 per-CPU变量 228 获取大的缓冲区 230 快速参考 231 第九章 与硬件通信 235 I/O端口和I/O内存 235 使用I/O端口 239 I/O端口示例 245 使用I/O内存 248 快速参考 254 第十章 中断...

    linux设备驱动程序

    内容简介 《LINUX设备驱动程序(第3版)》已针对Linux内核的2610版本彻底更新过了。内核的这个版本针对常见任务完成了合理化...vmalloc及其辅助函数 per-CPU变量 获取大的缓冲区 快速参考 ch09... ch10... ... ch18...

    嵌入式红绿灯控制系统

    就目前而言,在这一方面,比较普遍使用而又技术先进的主要是以CPLD为核心的实现方案和以MCU为核心的实现方案。 [2]但是将两者与嵌入式操作系统RTX51微控器软件相结合构成完整的交通信号灯控制系统的设计方案还比较少...

    嵌入式系统/ARM技术中的浅谈malloc与 kmalloc、cmalloc、realloc、new 的区别

     Malloc 返回一块内存地址的指针,否则会返回空指针null,这里要注意的是,当内存不再使用的时候,用free()函数进行对内存的释放。  2.calloc  作 用:calloc()函数有两个参数,分别为元素的数目和每个元素...

    虚拟网卡驱动源代码(原版)

    kfree (pkt); /* FIXME - in-flight packets ? */ } } /* * Buffer/pool management. */ struct snull_packet *snull_get_tx_buffer(struct net_device *dev) { struct snull_priv *priv = netdev_priv(dev)...

    Rootkit_on_Linux_x86_v2.6.pdf

     Using /dev/kmem and kmalloc  Using /dev/mem and kmalloc  “A rootkit is a set of software tools intended to conceal running processes, files or system data from the operating system… Rootkits ...

    嵌入式系统/ARM技术中的GPIO设备程序开发步骤

    GPIO驱动可以归类为Linux设备驱动的字符设备驱动,以下是开发它的一些具体步骤。... kmalloc()函数分配一段内存,这样就实现了Chrdevs向量表中指向设备驱动程序名称的指针。使用kfree释放内存。  

    kmallov函数解析

    对linux内核函数kamlloc的解析,希望能帮到大家

    os86:用于基本os开发的裸机沙箱

    实施: 多重启动分页和虚拟内存,具有高内存内核首次匹配kmalloc()和kfree()的简单堆分配简单的中断和异常简单协作多任务去做第三环,用户空间调度和抢先式多任务处理文件系统很多其他的东西移植到RISC-V并在...

    linux内存分配实例

    可见分配的内存的虚拟地址符合预期,__get_fre_page和kmalloc分配的内存在线性映射区,vmalloc分配的内存在非连续内存区

    Unreliable Guide To Hacking The Linux Kernel

    6.3. kmalloc()/kfree() include/linux/slab.h.........................................14 6.4. current include/asm/current.h...........................................................15 6.5. local_irq_...

Global site tag (gtag.js) - Google Analytics