内核申请内存的方法
Posted 今天天气眞好
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内核申请内存的方法相关的知识,希望对你有一定的参考价值。
文章目录
1.kmalloc
原型:void *kmalloc(size_t size, gfp_t flags);
①申请连续的物理内存,这对于要进行 DMA 的设备十分重要,但大小不能超过 128KB,其中有 16B 是被页描述符占用了。
②较常用的 flag 有 GFP_ATOMIC(分配内存的过程是一个原子过程)、 GFP_KERNEL(正常分配内存)、GFP_DMA(给 DMA 控制器分配内存)。
③对应的内存释放函数为 void kfree(const void *objp)。
2.vmalloc
原型:void *vmalloc(unsigned long size);
①申请虚拟地址连续的内存空间,但其对应的物理内存不一定连续,带来的好处就是可以分配较大的内存块,因此对申请的内存大小没有限制。
②对应的内存释放函数为 void free(const void *addr)。
③注意:vmalloc()和 vfree()可以睡眠,因此不能在中断上下文调用。
3.kzalloc
原型:void *kzalloc(size_t size, gfp_t flags);
①kzalloc()相对 kmalloc()只是额外增加了__GFP_ZERO 标志,除了申请内存外, 还会对申请到的内存内容清零。
②对应的释放函数也是 kfree()。
4.DMA
DMA是一种硬件机制,允许外围硬件设备直接与主存之间传输IO数据,而不需要CPU的干预。使用DMA机制可以大幅度提高设备通信的吞吐量。
5.ioremap
原型:void * ioremap(unsigned long offset,unsigned long size);
ioremap是一种更直接的内存”分配”方式,使用时直接指定物理起始地址和需要分配内存的大小,然后将该段物理地址映射到内核地址空间。ioremap用到的物理地址空间都是事先确定的,和上面的几种内存分配方式并不太一样,并且是分配一段新的物理内存。ioremap多用于设备驱动,可以让CPU直接访问外部设备的IO空间。ioremap能映射的内存由原有的物理内存空间决定,所以没有进行测试。
6.kmalloc和vmalloc以及malloc的区别
1.kmalloc和vmalloc都是分配的内核的内存,而malloc是分配的用户的内存
2.kmalloc保证分配的内存在物理上是来连续的,vmalloc保证分配的内存在虚拟地址空间上是连续的
3.kmalloc分配的大小是有限的,vmalloc和malloc分配的内存相对较大
4.内存只有在要被DMA访问的时候才需要物理上连续
5.vmalloc比kmalloc要慢
7.malloc的底层实现
1.malloc 函数的底层实现是操作系统有一个由可用内存块连接成的空闲链表
。 调用 malloc 时,它将遍历该链表寻找足够大的内存空间,将该块一分为二(一块与用户申请的大小相等,另一块为剩下来的碎片,会返回链表),调用 free 函数时,内存块会重新连接回链表。
2.若内存块过于琐碎无法满足用户需求,则操作系统会合并相邻的内存块。
8.内核程序中申请内存和应用程序时申请内存有什么区别?
答案:内核中申请内存空间用的是函数 kmalloc、kzalloc、vmalloc,应用程序申 请内存用的函数是 malloc。 解读: 157
(1)kmalloc/kzalloc 直接分配连续的物理地址(虚拟地址也是连续的)。 (2)vmalloc 分配连续的虚拟地址,但物理地址不一定连续。分配时实际分配了 物理内存,不过这个物理内存页面是在公共的页表进行了映射,并没有在本进程的页表 进行映射,当访问这段内存时,触发 do_page_fault 异常(缺页中断)才完成页表的同 步工作。(4)malloc 是用户空间申请内存的方法,分配连续的虚拟地址,物理地址一般不 会连续。在分配时并没有做实际物理页的分配动作,实际分配物理页的动作是在 do_page_fault 异常(缺页中断)处理中完成的。
以上是关于内核申请内存的方法的主要内容,如果未能解决你的问题,请参考以下文章
Linux内核空间内存申请函数kmallockzallocvmalloc的区别