用户空间内存分配
. malloc/free: 按字节分配内存
. valloc/vfree: 分配字节内存对齐
内核空间内存分配
. kmalloc/kree: 分配的内存物理上连续,只能在低端内存分配
. get_zeroed_page/free_page:分配一个页面(4K),并且该页面内容被清零,
只能在低端内存分配
. _gete_free_pages/free_pages: 分配指定页数的低端内存
. alloc_pages/_free_pages:分配指定页数的内存,可以从高端内存,也可以从低端
内存分配
. valloc/vfree:分配的内存在内核空间中连续,物理上无需连续。vmalloc由于不需要
物理上也连续,所以性能很差,一般只有在必须申请大块内存进才使用,例如动态
插入模块时
. 对于申请的内存必须释放,否则将导致系统错误。
. void *kmalloc(size_t size, gfp_t flags);
-size:
待分配内存大小(按字节计)
-flags:分配标志,用于控制kmalloc行为
-返回:分配到内核的虚拟地址,失败返回NULL
. void kfree(const void *objp)
-objp : 由kmalloc
返回的内核虚拟地址
. unsigned long get_zeroed_page(ftp_t gfp_mask);
- fgp_mask
:分配标志,用于控制kmalloc行为
-
返回:指向分配到的已经被清零的内存页面第一个字节的指针,失败返回NULL
. void free_page(unsigned long addr);
-addr:由get_zeroed_page返回的内核虚拟地址
_get_free_pages函数
. unsigned long _get_free_pages(gfp_t gft_mask, unsigned int
order);
- gfp_maks:分配标志, 用于控制_get_free_pages行为
- order:
请求或释放的页数的2的幂,例如:操作1页该值为0,操作16页该值为4,
如果该值太大会导致分配失败,该值允许的最大值依赖于体系结构
- 返回: 指向分配到连续内存区第一个字节的指针,失败返回NULL
free_pages函数
. void free_pages(unsigned long addr, unsigned int order);
-addr: 由_get_free_pages返回的内核虚拟地址
-order: _get_free_pages分配内在时使用的值
. int get_order(unsigned long size);
-size: 需要计算order值的大小(按字节计算)
-返回:_get_free_pages等函数需要的order值
vmalloc函数/vfree函数
. void *vmalloc(unsigned long size);
-size: 待分配的内在的大小,自动按页对齐
-返回: 分配到的内核虚拟地址, 失败返回NULL
. void vfree(const void *addr);
- addr: 由vmalloc返回的内核虚拟地址
内核内存分配标志
. GFP_KERNEL : 表示该次内存分配由内核态进程调用,返回是内核内存的正常分配,
该分配方式最常用。如果空闲空间不够,该次分配将使得进程进入睡眠,等待空闲
页的出现。
. GFP_ATOMIC: 用于分配请求不是来自于进程上下文,而是来自于中断,任务队列处理、
内核定时器等中断上下文的情况,此时不能进入睡眠。
虚拟地址和物理地址转换
.定义在arch/arm/include/asm/memory.h中
. unsigned long virt_to_phys(void *x);
- 虚拟地址转换为物理地址
. void *phys_to_virt(unsigned long x);
- 物理地址转换为虚拟地址
3.内核分配内存的方法:
kmalloc/kfree
get_zeroed_page/free_page
_get_free_pages/free_pages
分配的内存物理上连续,虚拟上也连续,在低端内存分配
vmalloc/vfree
分配的内存虚拟上连续,物理上不一定连续,一般用于分配较大的内存
分配内存的行为的标志:
GFP_KERNEL:如查使用这个宏,告诉内核请努力为我分配好内在,如果内存不足,进入休眠状态,
等待空闲页的出现。所以不能用在中断上下文,不能用在中断屏蔽保护的临界区,不能用在自旋锁
保护的临界区
GFP_ATOMIC:如果使用这个宏,内存不足时(空闲不够),内核分配内存就会立即返回,所以用在中断
上下文。