linux-kernel – 将mmap内核引导参数保留的映射内存映射到用户空
发布时间:2020-12-14 02:10:50 所属栏目:Linux 来源:网络整理
导读:正如在 this问题中讨论的那样,我使用内核启动参数memmap = 8G $64G在启动时保留内存块 我编写了一个character driver内核模块,在初始化期间会执行这个保留内存块的ioremap. 正如here所解释的那样,在我的驱动程序mmap中,我需要做的是对ioremap返回的内存块指
正如在
this问题中讨论的那样,我使用内核启动参数memmap = 8G $64G在启动时保留内存块
我编写了一个character driver内核模块,在初始化期间会执行这个保留内存块的ioremap. 我在3.0 linux内核上运行它.我的用户空间应用程序打开此内存块作为驱动程序安装的设备.当我从使用空间应用程序执行mmap时,我看到系统挂起.我的dmesg没有提供太多信息. 有什么投入? static int __init myDev_module_init(void) { int retval; myDev_major = register_chrdev(0,DEVICE_NAME,&myDevfops); if (myDev_major < 0) { err("failed to register device: error %dn",myDev_major); retval = myDev_major; goto FAILED_CHRDEVREG; } myDev_class = class_create(THIS_MODULE,CLASS_NAME); if (IS_ERR(myDev_class)) { err("failed to register device class '%s'n",CLASS_NAME); retval = PTR_ERR(myDev_class); goto FAILED_CLASSREG; } myDev_device = device_create(myDev_class,NULL,MKDEV(myDev_major,0),CLASS_NAME "_" DEVICE_NAME); if (IS_ERR(myDev_device)) { err("failed to create device '%s_%s'n",CLASS_NAME,DEVICE_NAME); retval = PTR_ERR(myDev_device); goto FAILED_DEVREG; } 这里myDev.startOffset初始化为#defined 64GB,myDev.memSize为8GB. //myDev.startAddr = ioremap(myDev.startOffset,myDev.memSize); //memset_io(myDev.startAddr,myDev.memSize); return 0; FAILED_DEVREG: class_unregister(myDev_class); class_destroy(myDev_class); FAILED_CLASSREG: unregister_chrdev(myDev_major,DEVICE_NAME); FAILED_CHRDEVREG: return -1; } static int myDev_device_open(struct inode* inode,struct file* filp) { dbg(""); if ( ((filp->f_flags & O_ACCMODE) == O_WRONLY) || ((filp->f_flags & O_ACCMODE) == O_RDWR) ) { warn(" Opening the device with write accessn"); //return -EACCES; } info(" device Open is calledn"); filp->private_data = &myDev; return 0; } 而mmap非常简单. ? static int myDev_device_mmap(struct file * f,struct vm_area_struct * vma) { int retval = 0; struct myDevDev * pDev = (struct myDevDev *)(f->private_data); dbg(""); if(vma) { if(f) { if(f->private_data) warn("mmap: f->private_data : %pn",f->private_data); else warn(" mmap :f->private_data : NULL n"); } else { warn("mmap: f :NULLn"); } warn(": mmap: vm start : %lun",vma->vm_start); warn(" mmap: vm end : %lun",vma->vm_end); warn(" mmap: vm pg offset : %lun",vma->vm_pgoff); //retval = remap_pfn_range(vma,vma->vm_start,pDev->startOffset >> PAGE_SHIFT,pDev->memSize,PAGE_SHARED) ; // retval = remap_pfn_range(vma,pDev->startAddr >> PAGE_SHIFT,PAGE_SHARED) ; //retval = remap_pfn_range(vma,pDev->startAddr,PAGE_SHARED); retval = remap_pfn_range(vma,PAGE_SHARED); if(retval <0) { warn(" ERROR : in mapping kernel virtual space to user space return value : %d n",retval); return -EINVAL; } //if(0) { vma->vm_flags |=VM_LOCKED; vma->vm_ops = &myRemapVMOps; vma->vm_flags |= VM_RESERVED; vma->vm_private_data = f->private_data; myDevice_VMA_Open(vma); } } else { warn ("vma is NULL"); } dbg(" Done "); warn("mmpaing done : n"); return 0; } 从我的用户空间应用程序我正在做以下事情: ? int err,i=0; void * mptr = NULL; printf(" Access the reserved memory chunk n "); int fd = open("/dev/myDevice",O_RDWR | O_SYNC); if(fd <=0) { printf("ERROR: my device driver is not loaded n"); return 1; } printf("n mmaping mem chunk size :%llu pagesize :%lu input mptr :%pn",sz,getpagesize (),mptr); mptr = mmap(0,PROT_READ | PROT_WRITE,MAP_SHARED | MAP_LOCKED,fd,0); if(mptr == MAP_FAILED) { close(fd); perror("Error mmapping the file"); printf("nmmapped mem address %pn",mptr); exit(1); } printf("nmmapped mem address %pn",mptr); //char * ptr = (char *)mptr; //*ptr = 'a'; //int * pInt = (int *) (((char *) mptr)+1); //for(;i<10000; ++i) { // pInt[i] = 2*i; } /* free the mmapped memory */ if (munmap(mptr,sz) == -1) { perror("Error un-mmapping the file"); } close(fd); 观察: 我没有看到尺寸反映在(vma-> vm_end – vma-> vm_start)中,由于某种原因它始终是4K. 解决方法
>您可以逐步使用标准的phram驱动程序从用户空间访问您的内存.不需要编码.内核重新??编译最多. >你真的有超过64Gb的RAM吗?你的硬件真的支持吗?
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- Linux笔记:关机重启登出
- linux-kernel – Linux内核 – 时钟框架 – clk_prepare /
- LINUX教学:使用phpexcel类实现excel导入mysql数据库功能(实
- linux – iotop显示kswapd0为99.99%,0%DISK READ和DISK W
- 关于linux input device输入子系统架构及android中的框架
- Linux下nginx编译安装教程和编译参数详解
- Haskell卷曲帮助
- linux:通过procfs确定文件句柄标识
- Linux中 groupmems命:更改和查看组成员
- Linux Virtual Server是旧的还是静止不动?