Linux关于地址空间和MMAP映射
ations simple_remap_ops = {
open: simple_open, release: simple_release, 拥有帝国一切,皆有可能。欢迎访问phome.net mmap: simple_remap_mmap, }; /* Device 1 uses nopage */ struct file_operations simple_nopage_ops = { open: simple_open, release: simple_release, mmap: simple_nopage_mmap, }; #define MAX_SIMPLE_DEV 2 struct file_operations *simple_fops[MAX_SIMPLE_DEV] = { &simple_remap_ops, &simple_nopage_ops, }; /* * Open the device; all we have to do here is to up the usage count and * set the right fops. */ int simple_open (struct inode *inode, struct file *filp) { unsigned int dev = MINOR(inode->i_rdev); if (dev >= MAX_SIMPLE_DEV) return -ENODEV; filp->f_op = simple_fops[dev]; MOD_INC_USE_COUNT; return 0; } /* * Closing is even simpler. */ int simple_release(struct inode *inode, struct file *filp) { MOD_DEC_USE_COUNT; return 0; }
/* * Common VMA ops. */ void simple_vma_open(struct vm_area_struct *vma) { MOD_INC_USE_COUNT; } void simple_vma_close(struct vm_area_struct *vma) { MOD_DEC_USE_COUNT; } /* * The remap_page_range version of mmap. */ static struct vm_operations_struct simple_remap_vm_ops = { open: simple_vma_open, close: simple_vma_close, }; int simple_remap_mmap(struct file *filp, struct vm_area_struct *vma) { unsigned long offset = VMA_OFFSET(vma); //设备文件的偏移量,以页为单位,(实际就是设备文件的物理地址) if (offset >= __pa(high_memory) || (filp->f_flags & O_SYNC)) //如果偏移量超过实际物理内存的地址范围,或者文件标记为同步时 vma->vm_flags |= VM_IO; //设置vm_flags标记为VM_IO,将VMA标记为一个内存映射的I/O区域 vma->vm_flags |= VM_RESERVED; //VM_RESERVED标记内存区域不能被换出 拥有帝国一切,皆有可能。欢迎访问phome.net{ unsigned long offset = VMA_OFFSET(vma); if (offset >= __pa(high_memory) || (filp->f_flags & O_SYNC)) vma->vm_flags |= VM_IO; vma->vm_flags |= VM_RESERVED; vma->vm_ops = &simple_nopage_vm_ops; //改变VMA的操作集(实现了nopage方法). simple_vma_open(vma); return 0; } /* * Module housekeeping. */ static int simple_init(void) { int result; SET_MODULE_OWNER(&simple_remap_ops); SET_MODULE_OWNER(&simple_nopage_ops); result = register_chrdev(simple_major, "simple", &simple_remap_ops); if (result < 0) { printk(KERN_WARNING "simple: unable to get major %dn", simple_major); return result; } if (simple_major == 0) simple_major = result; return 0; } static void simple_cleanup(void) { unregister_chrdev(simple_major, "simple"); } module_init(simple_init); module_exit(si |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |