快速业务通道

Linux关于地址空间和MMAP映射

作者 佚名技术 来源 Linux系统 浏览 发布时间 2012-04-24
ct 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标记内存区域不能被换出

  {

  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(simple_cleanup);

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号