1,我们在用户空间又申请空间一说,在内核空间同样有此一说:
现在我们简要说明一下他们的区别和对比:
kmalloc/kfree //内存分配物理上连续,只能低端内存分配
get_zeroed_page/free_page //分配一个页面并清零,只能低端内存分配
_get_free_page/free_pages //分配指定页数内存并清零,只能低端内存分配
alloc_pages/_free_pages //分配指定页数内存并清零,可低端内存分配,也可高端内存分配
vmalloc/vfree //分配的空间在内核空间连续,物理上无连续,所以性能差,一般只用于大块内存的申请。
2,举例来看看他们的用法:kmalloc和kfree以及get_zeroed_page和free_page的举例:
#include<linux/init.h>
#include<linux/module.h>
#include<linux/fs.h>
#include<linux/slab.h>
MODULE_LICENSE("Dual BSD/GPL");
static char* buf1 = NULL;
static char* buf2 = NULL;
static int __init kernelspacemalloc_init(void)
{
printk(KERN_EMERG "kernel space malloc init enter\n");
buf1 = (char*)kmalloc(100,GFP_KERNEL);//GFP_KERNEL 表示申请的内存供内核进程调用
if(IS_ERR(buf1))
{
printk(KERN_EMERG " kernelspacemalloc kmalloc failure\n");
goto failure_alloc_buf1;
}
memset(buf1,0,100);
strcpy(buf1,"strcpy my message to kernel space successfully\n");
printk("kernelspacemalloc:get buf = %s\n",buf1);
buf2 = (char*)get_zeroed_page(GFP_KERNEL);
if(IS_ERR(buf2))
{
printk(KERN_EMERG " kernelspacemalloc kmalloc failure\n");
goto failure_alloc_buf2;
}
memset(buf2,0,100);
strcpy(buf2,"strcpy my message to kernel space successfully\n");
printk("kernelspacemalloc:get buf2 = %s\n",buf2);
return 0;
failure_alloc_buf2: //buf2失败了记住退出之前要释放buf1申请的内存
kfree(buf1);
buf1 = NULL;
failure_alloc_buf1:
return -ENOMEM;
}
static void __exit kernelspacefree_exit(void)
{
printk(KERN_EMERG "kernel space free exit enter\n");
free_page((unsigned long)buf2);
buf2 = NULL;
//free buf1
kfree(buf1);
buf1 = NULL;
}
module_init(kernelspacemalloc_init);
module_exit(kernelspacefree_exit);
MODULE_AUTHOR("taotao");
MODULE_VERSION("0.0.1");
makefile如下:
obj-m+=space_malloc.o
CONFIG_MODULE_SIG=n
all:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) clean
运行结果如下:
3,vmalloc和vfree 以及 __get_free_pages和free_pages的使用:
/********************
vmalloc 分配的内存内核空间连续,物理上不连续,一般用于申请大块内存。
**********************/
#include<linux/init.h>
#include<linux/module.h>
#include<linux/fs.h>
#include<linux/slab.h>
#include<linux/vmalloc.h>
MODULE_LICENSE("Dual BSD/GPL");
static unsigned char* kernelkmalloc_buf = NULL;
static unsigned char* kernelpagefree_buf = NULL;
static unsigned char* kernelvmalloc_buf = NULL;
static int order = 1;//请求或释放的页数的2的幂,操作1页该值为0,操作16页该值为4
static int __init kernelspacevmalloc_init(void)
{
printk(KERN_EMERG "kernel space malloc vmalloc init enter\n");
printk("file = %s,function = %s, line = %d\n",__FILE__,__FUNCTION__,__LINE__);
//kmalloc GEP_KERNEL 内核态进程调用 GFP_ATOMIC 用于中断,任务队列,内核定时器的中断上下文
//_GFP_DMA 用于DMA访问内存(16M以下的物理内存) _GFP_HIGHMEM 高端内存
kernelkmalloc_buf = (char*)kmalloc(100,GFP_KERNEL);//GFP_KERNEL 表示申请的内存供内核进程调用
if(IS_ERR(kernelkmalloc_buf))
{
printk(KERN_EMERG "kernelspacemalloc kmalloc failure\n");
goto failure_alloc_buf1;
}
memset(kernelkmalloc_buf,0,100);
strcpy(kernelkmalloc_buf,"strcpy my message to kernel space successfully\n");
printk(KERN_EMERG "kernelspacemalloc:get buf = %s\n",kernelkmalloc_buf);
printk(KERN_EMERG "kmalloc get memory adress 0x%lx!\n",(unsigned long)kernelkmalloc_buf);
kernelpagefree_buf = (unsigned char*)__get_free_pages(GFP_KERNEL,order);
if(IS_ERR(kernelpagefree_buf))
{
printk(KERN_EMERG " kernelspacemalloc kmalloc failure\n");
goto failure_alloc_buf2;
}
memset(kernelpagefree_buf,0,100);
strcpy(kernelpagefree_buf,"strcpy my message to kernel space successfully\n");
printk(KERN_EMERG "kernelspacemalloc:get buf2 = %s\n",kernelpagefree_buf);
printk(KERN_EMERG "get_free_pages get memory adress 0x%lx!\n",(unsigned long)kernelpagefree_buf);
kernelvmalloc_buf = (unsigned char*)vmalloc(1024*1024);
if(IS_ERR(kernelvmalloc_buf))
{
printk(KERN_EMERG " kernelspacemalloc vmalloc failure\n");
goto failure_alloc_buf3;
}
memset(kernelvmalloc_buf,0,100);
strcpy(kernelvmalloc_buf,"strcpy my message to kernelvmalloc_buf space successfully\n");
printk(KERN_EMERG "kernelspacemalloc:kernelvmalloc_buf = %s\n",kernelvmalloc_buf);
printk(KERN_EMERG "kernelvmalloc_buf get memory adress 0x%lx!\n",(unsigned long)kernelvmalloc_buf);
return 0;
failure_alloc_buf3:
free_pages((unsigned long)kernelpagefree_buf,order);
kernelpagefree_buf = NULL;
failure_alloc_buf2: //buf2失败了记住退出之前要释放buf1申请的内存
kfree(kernelkmalloc_buf);
kernelkmalloc_buf = NULL;
failure_alloc_buf1:
return -ENOMEM;
}
static void __exit kernelspacevfree_exit(void)
{
printk(KERN_EMERG "kernel space vmalloc free exit enter\n");
printk("file = %s,function = %s, line = %d\n",__FILE__,__FUNCTION__,__LINE__);
vfree(kernelvmalloc_buf);
kernelvmalloc_buf = NULL;
free_pages((unsigned long)kernelpagefree_buf,order);
kernelpagefree_buf = NULL;
//free buf1
kfree(kernelkmalloc_buf);
kernelkmalloc_buf = NULL;
}
module_init(kernelspacevmalloc_init);
module_exit(kernelspacevfree_exit);
MODULE_AUTHOR("taotao");
MODULE_VERSION("0.0.1");
//Makefile
obj-m+=space_vmalloc.o
all:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) clean
运行结果如下: