a.分配
| #include <linux/gfp.h> 1. struct page * alloc_pages( unsigned int gfp_mask, unsigned int order); //分配2的order次方个连续的物理页。 2. void *page_address( struct page *page); //返回一个指针,指向给定物理页当前的虚拟地址 3. unsigned long __get_free_pages( unsigned int gfp_mask, unsigned int order); //相当于上两个函数结合 4. struct page * alloc_page( unsigned int gfp_mask); 5. unsigned long __get_free_page( unsigned int gfp_mask); 6. unsigned long get_zeroed_page( unsigned int gfp_mask); //只分配一页 |
b.gfp_mask标志
这个标志决定了内核在分配内存时的行为,以及从哪里分配内存。
| #include <linux/gfp.h> #define GFP_ATOMIC //原子分配,不会休眠,可用于中断处理。 #define GFP_KERNEL //首选,内核可能会睡眠,用在进程上下文中 |
c.释放页
| void __free_pages(struct page *page, unsigned int order); void free_pages(unsigned long addr, unsigned int order); void free_page(unsigned long addr); |
注意!只能释放属于你的页。错误的参数可能导致内核崩溃。
(3)通过kmalloc获取内存
kmalloc和malloc很象,是内核中最常用的内存分配函数。
kmalloc不会对分配的内存区域清0,分配的区域在物理内存中是连续的。
a.分配
| #include <linux/slab.h> void *kmalloc(size_t size, int flags) |
size是要求分配的内存的大小
kmalloc的参数flags可以控制kmalloc分配时的行为。和alloc_page时使用的标志是一致的。注意,kmalloc不能分配高端内存
b.释放
| #include <linux/slab.h> void kfree(const void *ptr); |
如果要释放的内存已经被释放了,或者释放属于内核其他部分的内存,则会产生严重的后果。调用kfree(NULL)是安全的。
要注意!内核只能分配一些预定义的,固定大小的字节数组。kmalloc能处理的最小内存块是32或64。由于kmalloc分配的内存在物理上连续,所以有分配上限,通常不要超过128KB。
(4)通过vmalloc获得内存
vmalloc()分配的内存虚拟地址是连续的,但物理地址不需要连续。这也是malloc()的分配方式。vmalloc分配非连续的内存块,再修改页表,把内存映射到逻辑空间连续的区域内。
大多数情况下,只有硬件设备需要得到物理地址连续的内存,内核可以使用通过vmalloc获得的内存。但内核中多采用kmalloc,这主要是考虑性能,因为vmalloc会引起较大的TLB抖动,除非映射大块内存时采用vmalloc。例如模块动态加载时,就是加载到通过vmalloc分配的内存。
vmalloc在<linux/vmalloc.h>声明,在<mm/vmalloc.c>定义,用法和malloc()相同。








