首页 > 系统相关 >mmap内存映射 --- 字符设备驱动,用户空间和内核空间映射到同一个物理内存

mmap内存映射 --- 字符设备驱动,用户空间和内核空间映射到同一个物理内存

时间:2023-12-17 22:45:49浏览次数:31  
标签:struct 映射 mmap vm vma 内存 tiny4412 include

内存映射可实现用户程序对设备驱动内存的直接存取

示例代码: 驱动层

#include <linux/init.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/slab.h> //定义kmalloc接口  
#include <asm/io.h>     //定义virt_to_phys接口  
#include <linux/mm.h>   //remap_pfn_range
#include <linux/vmalloc.h>
#include <linux/delay.h>
#define MM_SIZE 4096  
static char *buf= NULL;  
static int tiny4412_open(struct inode *my_indoe, struct file *my_file)
{
   buf=(char *)kmalloc(MM_SIZE,GFP_KERNEL);//内核申请内存只能按页申请,申请该内存以便后面把它当作虚拟设备  
   if(buf==NULL)
   {
      printk("error!\n");
      return 0;
   }
   strcpy(buf,"123456789");
   printk("open ok\n");
   return 0;
}

static int tiny4412_release(struct inode *my_indoe, struct file *my_file)
{
   printk("驱动层打印=%s\n",buf);
   kfree(buf); /*释放空间*/
   printk("open release\n");
   return 0;
}

static int tiny4412_mmap(struct file *myfile, struct vm_area_struct *vma)
{
   vma->vm_flags |= VM_IO;//表示对设备IO空间的映射  
   vma->vm_flags |= VM_RESERVED;//标志该内存区不能被换出,在设备驱动中虚拟页和物理页的关系应该是长期的,应该保留起来,不能随便被别的虚拟页换出  

    vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);    //修改访问保护属性

   if(remap_pfn_range(vma,//虚拟内存区域,即设备地址将要映射到这里  
                  vma->vm_start,//虚拟空间的起始地址  
                  virt_to_phys(buf)>>PAGE_SHIFT,//与物理内存对应的页帧号,物理地址右移12位  
                  vma->vm_end - vma->vm_start,//映射区域大小,一般是页大小的整数倍  
                  vma->vm_page_prot))//保护属性,  
   {  
      return -EAGAIN;  
   }  

   printk("tiny4412_mmap ok\n");
   return 0;
}

static struct file_operations tiny4412_fops=
{
   .open=tiny4412_open,
   .release=tiny4412_release,
   .mmap=tiny4412_mmap
};

static struct miscdevice misc={
   .minor=255,
   .name="tiny4412_mmap",  // /dev/下的名称
   .fops=&tiny4412_fops,
};

static int __init hello_init(void)
{
   /*1. 注册杂项字符设备*/
   misc_register(&misc);
   printk("hello_init 驱动安装成功!\n");
   return 0;
}

static void __exit hello_exit(void)
{
    /*2. 注销*/
    misc_deregister(&misc);
   printk("hello_exit驱动卸载成功!\n");
}

module_init(hello_init); 
module_exit(hello_exit); 

MODULE_AUTHOR("www.wanbangee.com");      //声明驱动的作者
MODULE_DESCRIPTION("hello 模块测试"); //描述当前驱动功能
MODULE_LICENSE("GPL");  //驱动许可证。支持的协议GPL。

 

示例代码: 应用层

#include <stdio.h>
#include <sys/mman.h>

unsigned char *fbmem=NULL;
unsigned char buff[10];
int main(int argc,char**argv)
{
   int fd;
   fd=open("/dev/tiny4412_mmap",2);
   if(fd<0)
    {
      printf("驱动打开失败!\n");
      return -1;  
    }
   fbmem =(unsigned char *)mmap(NULL,4096,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
   if(fbmem==NULL)
   {
     printf("映射错误!\n");
   }
   printf("应用层打印1=%s\n",fbmem); //打印出123456789
   memcpy(fbmem,"987654321",10);   //向映射空间拷贝数据
   memcpy(buff,fbmem,10);          //将映射空间的数据拷贝出来
   printf("应用层打印2=%s\n",buff); //打印出987654321
   close(fd);
   return 0;
}

 

标签:struct,映射,mmap,vm,vma,内存,tiny4412,include
From: https://www.cnblogs.com/god-of-death/p/17910011.html

相关文章

  • linux 进程间通信 --- 共享内存(POSIX 版本)
    POSIX进程间通信POSIX进程间通信(InterprocessCommunication,IPC)是SystemV进程间通信的变体。它是在Solaris7发行版中引入的。与SystemV对象类似,POSIXIPC对象的属主、属主的组以及其他用户具有读取和写入权限,但是没有执行权限。POSIXIPC对象的属主无法将对象......
  • Servlet中访问路径配置为/*时,使用请求转发造成内存溢出
    一、问题由来最近在测试Servlet的请求转发功能,准备抽取一个公共的PageJumpTestServlet,用来做页面跳转功能。这样不用每次在测试的时候,都单独写一个Servlet用来做页面跳转。自己最初的设想时,在路径配置的时候使用/toPage/*,访问地址示例http://localhost:8080/javaWeb/toPage......
  • Spring如何j将xml配置映射为BeanDefinition
    Spring的常用配置文件是applicationContext.xml文件,最简单的,一般我们都会添加这样的配置:<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-ins......
  • 多开软件对Windows电脑内存的占用情况
    当今,许多人在日常使用电脑时可能会遇到需要同时打开多个应用程序或者多个账户的情况。为了应对这种需求,一些用户选择使用多开软件来实现在同一台电脑上同时打开多个应用程序或账户的功能。然而,使用多开软件可能会对Windows电脑的内存占用产生一定的影响。首先,让我们来了解一下多......
  • 嵌入式系统中内存泄露的原因和避免措施
    在嵌入式系统开发中,内存泄露是一个常见而又隐蔽的问题,可能导致系统性能下降、不稳定甚至崩溃。本文将深入探讨嵌入式系统中内存泄露的原因,并提供一些避免措施,通过详细的代码演示展示如何在嵌入式环境中防范内存泄露。1.内存泄露的原因1.1动态内存分配未释放在嵌入式系统中,动态内......
  • Redis不同版本,内存分配,硬件的性能研究
    Redis不同版本,内存分配,硬件的性能研究前言Konwmore!Domore!Gainmore!骨折之后开始减肥.前段时间跳绳导致膝盖不舒服,现在改骑车和走路.在有限的没人有烦的时间里,还是想能够多学习一些东西.之前了解了isolcpus现在突然想内存分配可能也有性能影响.所以想研......
  • 第四章:mapper映射文件存放位置、springboot支持事务
    一、mapper映射文件存放位置二、springboot支持事务......
  • unigui显示uniTreeVview使用TUniTreeNode内存泄漏的问题【14】
    uniTreeVviewc创建一个tree,显示患者姓名(PatientName)。因为需要用到患者ID(PatientID),所以使用help:TPatientTreeNode=class(TUniTreeNode)//strictprivateFPatientID:string;functionGetPatientID:string;procedureSetPatientID(constValue:string)......
  • JVM虚拟机系统性学习-运行时数据区(方法区、程序计数器、直接内存)
    方法区方法区本质上是Java编译后代码的存储区域,存储了每一个类的结构信息,如:运行时常量池、成员变量、方法、构造方法和普通方法的字节码指令等内容方法区主要存储的数据如下:Class类型信息,如该Class为class类、接口、枚举、注解,类的修饰符等等信息方法信息(方法名称、方法返回......
  • 直播平台搭建,Java 内存溢出的排查方法
    直播平台搭建,Java内存溢出的排查方法JDK自带命令jstat-gcutil3381625020#监控jvm的内存使用情况jps-ml#输出虚拟机启动时传递给主类main()的参数,输出主类的全名jmap-F-dump:live,format=b,file=dump.bin85962#dump堆内存#分析方法#可以使用Vi......