linux驱动学习笔记---内存映射(八)

 

使用内存映射的好处是可以加快我们应用与内核数据传送的速度,一般的调用需要在应用层申请空间,同时需要在内核申请空间,有内存映射就可以只申请一个空间就可以. 

加载函数中申请空间

	//分配内存
	key_dev->virt_mem = kzalloc(PAGE_SIZE,  GFP_KERNEL);

卸载函数中释放空间

kfree(key_dev->virt_mem);

fops中实现mmp函数 

int key_drv_mmap(struct file *filp, struct vm_area_struct *vma)
{

	unsigned long addr;

	addr = virt_to_phys(key_dev->virt_mem);

	//将当前内存映射到用户空间
	//参数1--描述应用空间的mmap函数的需求(参数)
	//参数2--应用空间的起始位置
	//参数3--内核空间的内存的物理地址的页地址
	//参数4--内存的大小
	//参数5--权限
	if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT,
					PAGE_SIZE, vma->vm_page_prot)) {
		printk(KERN_ERR "%s: io_remap_pfn_range failed\n",
			__func__);
		return -EAGAIN;
	}

	return 0;
}

 phys_to_virt是将已经映射的物理内存的地址转换为虚拟地址

PAGE_SHIFT为12 向右移动实际为除以2^12  在内核中一页的地址个数为2^12个实际为4K空间(一个地址对应一个字节)

所以addr 右移动12位实际为其页地址

 

应用层实现mmp

	//演示mmap的使用

	//参数1---映射到用户进程空间的起始位置,一般填NULL, 由系统自动分配
	//参数2--映射的长度
	//参数3--映射之后的内存访问权限
	/*
		PROT_EXEC  Pages may be executed.

       PROT_READ  Pages may be read.

       PROT_WRITE Pages may be written.

       PROT_NONE  Pages may not be accessed.

	*/
	//参数4--是否私有或者共享--MAP_SHARED/MAP_PRIVATE
	//参数5--文件描述符
	//参数6--映射内核中内存的起始的偏移量,一般都是填0
	//返回值--映射成功之后的用户空间的起始地址
	paddr = (char *)mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd,  0);
	if(MAP_FAILED == paddr)
	{
		perror("mmap");
		exit(1);
	}

	memcpy(paddr, test_data, strlen(test_data));

	//测试是否成功
	sleep(1);
	memcpy(rbuf, paddr, 128);
	printf("rbuf = %s\n", rbuf);

 

文件io中的ioctl和mmap接口

    应用程序如何使用mmap:
     #include <sys/mman.h>

     
        //参数1---映射到用户进程空间的起始位置,一般填NULL, 由系统自动分配
        //参数2--映射的长度
        //参数3--映射之后的内存访问权限
        /*
            PROT_EXEC  Pages may be executed.

           PROT_READ  Pages may be read.

           PROT_WRITE Pages may be written.

           PROT_NONE  Pages may not be accessed.

        */
        //参数4--是否私有或者共享--MAP_SHARED/MAP_PRIVATE
        //参数5--文件描述符
        //参数6--映射内核中内存的起始的偏移量,一般都是填0
        //返回值--映射成功之后的用户空间的起始地址
       void *mmap(void *addr, size_t length, int prot, int flags,
                  int fd, off_t offset);
       int munmap(void *addr, size_t length);

    -----------------------------------------------------

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值