嵌入式技术论坛
直播中

王平

7年用户 1339经验值
私信 关注
[经验]

LINUX内核中的内存是如何进行分配的

1、devm_kzalloc & devm_kfree

函数devm_kzalloc和kzalloc一样都是内核内存分配函数,但是devm_kzalloc是跟设备(装置)有关的,当设备(装置)被拆卸或者驱动(驱动程序)卸载(空载)时,内存会被自动释放。另外,当内存不再使用时,可以使用函数devm_kfree()释放。而kzalloc没有自动释放的功能,用的时候需要小心使用,如果忘记释放,会造成内存泄漏。
函数原型为

void * devm_kzalloc (struct device * dev, size_t size, gfp_t gfp);
1
dev
Device to allocate memory for
申请内存的目标设备。
size
Allocation size
申请的内存大小
gfp
Allocation gfp flags
申请内存的类型标志

2、kmalloc & kfree

分配的内存物理上连续(虚拟上也连续),只能在低端内存分配(直接内存映射区)。

void *kmalloc(size_t size, gfp_t gfp);

size: 待分配内存大小(按字节计算)
gfp: 分配标志,用于控制kmalloc行为。

3、get_zeroed_page & free_page

unsigned long get_zeroed_page(gfp_t gfp_mask);

gfp: 分配标志,用于控制kmalloc行为。
基于kmalloc实现。
分配的内存物理上连续,分配一个页面(4K),并且该页面内容被清零,只能在低端内存分配。

4、__get_free_pages & free_pages

unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order);

gfp_mask: 分配标志,用于控制kmalloc行为
order: 请求或者释放的页数的2的幂,例如:操作1页,该值为0,操作16页该值为4.如果该值太大会寻址分配失败,该值允许的最大值依赖于体系结构。

分配的内存物理上连续,分配指定页数的底端内存。(如果分配太大内存几百兆或者上G的内存,一般可以通过Uboot启动参数来实现(bootmemory)。

int get_order(unsigned long size);

size: 需要计算order值的大小(按字节计算)
返回:__get_free_pages等函数需要的order值

5、alloc_pages & __free_pages

分配的内存物理上连续,分配指定页数的内存,可以从高端内存,也可以从底端内存分配,通过宏指定。

6、 vmalloc & vfree

void *vmalloc(unsigned long size);

size:待分配的内存的大小,自动按页对齐。

默认在动态内存映射区分配。分配的内存在内核空间中连续(虚拟连续),物理上无需连续。vmalloc由于不需要物理上也连续,所以性能很差,一般只有在必须申请大块内存时才使用,例如动态插入模块时。

7、内存分配标志

1、GFP_KERNEL:

表示该次内存 分配由内核进程调用,凡是内核内存的正常分配,该分配方式最常用。如果空闲空间不足,该次分配将使得进程进入睡眠,等待空闲页出现。不能在中断上下文、自旋锁保护的临界区和中断屏蔽保护的临界区使用。

2、GFP_ATOMIC:

用于分配请求不是来自于进程上下文,而是来自于中断、任务队列处理、内核定时器等中断上下文的情况,此时不能进入休眠。如果空闲内存不足,立即返回。

原作者:不止冬雷和夏雪

更多回帖

发帖
×
20
完善资料,
赚取积分