代码学习inux内核驱动(三)
内存分配函数
#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
/******************************************************
内存区分为:ZONE_DMA,ZONE_NORMAL,ZONE_HIGH
void * kmalloc(int count, int flags);
用于在ZONE_NORMAL区分配内存,内存连续
GFP_KERNEL:用于进程上下文分配内存,允许睡眠等待
GFP_ATOMIC:用于中断上下文分配内存,不允许等待以获取空闲页
void * kzalloc(int count, int flags);
将获取的内存清0
void * vmalloc(unsigned long count)
返回内核虚拟地址,分配的内存可能不连续,不能用于DMA
kfree()
vfree()
virt_to_phys
ioremap_nocache
调用ioremap_nocache()函数之后,返回一个线性地址,此时CPU 可以访问设备的内存(已经将其映射到了线性地址空间中了),
ioremap_nocache进行一系列平台相关的操作使得CPU可以通过readb/readw/readl/writeb/writew/writel等IO函数进行访问
ioremap
iounmap
******************************************************/
MODULE_AUTHOR("xyzeng");
MODULE_LICENSE("Dual BSD/GPL");
static int code_case_mem_init(void)
{
printk("[%s,%d] enter!\n",__FUNCTION__,__LINE__);
char *p = (char *) kmalloc(32,GFP_KERNEL);
if(p == NULL)
printk("kmalloc GFP_KERNEL NULL");
else{
printk("kmalloc GFP_KERNEL :%x\n",p);
long addr = virt_to_phys((volatile void *)p);
printk("kmalloc GFP_KERNEL phy addr:%lx\n",addr);
kfree(p);
}
p = (char *) kzalloc(32,GFP_ATOMIC);
if(p == NULL)
printk("kzalloc GFP_ATOMIC NULL");
else{
printk("kzalloc GFP_ATOMIC :%x\n",p);
kfree(p);
}
p = (char *) vmalloc(32);
if(p == NULL)
printk("vmalloc NULL");
else{
printk("vmalloc :%x\n",p);
long addr = virt_to_phys((volatile void *)p);
printk("vmalloc phy addr:%lx\n",addr);
vfree(p);
}
#define VSYNC_MUX 0x020E01DC
void __iomem * vir = ioremap_nocache(VSYNC_MUX,4);
printk("ioremap_nocache vir:%x\n",vir);
long addr = virt_to_phys((volatile void *)vir);
printk("ioremap_nocache phy:%x\n",addr);
iounmap(vir);
return 0;
}
static void code_case_mem_exit(void)
{
printk("[%s,%d] enter!\n",__FUNCTION__,__LINE__);
}
module_init(code_case_mem_init);
module_exit(code_case_mem_exit);