淘先锋技术网

首页 1 2 3 4 5 6 7

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

运行结果如下: