| 
              reserve_virt_addr = ioremap(mem_start *1024 * 1024, mem_size *1024 * 1024);  printk("reserve_virt_addr = 0x%lx\n", (unsigned long)reserve_virt_addr);  if (reserve_virt_addr)  {   int i;   for (i = 0; i < mem_size *1024 * 1024; i += 4)   {    reserve_virt_addr[i] = 'a';    reserve_virt_addr[i + 1] = 'b';    reserve_virt_addr[i + 2] = 'c';    reserve_virt_addr[i + 3] = 'd';   }  }  else  {   unregister_chrdev(major, "mmapdrv");   return - ENODEV;  }  return 0; }
  /* remove the module */ void cleanup_module(void) {  if (reserve_virt_addr)   iounmap(reserve_virt_addr);
   unregister_chrdev(major, "mmapdrv");  return ; }
  int mmapdrv_open(struct inode *inode, struct file *file) {  MOD_INC_USE_COUNT;  return (0); }
  int mmapdrv_release(struct inode *inode, struct file *file) {  MOD_DEC_USE_COUNT;  return (0); }
  int mmapdrv_mmap(struct file *file, struct vm_area_struct *vma) {  unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;  unsigned long size = vma->vm_end - vma->vm_start;
   if (size > mem_size *1024 * 1024)  {   printk("size too big\n");   return ( - ENXIO);  }
   offset = offset + mem_start * 1024 * 1024;
   /* we do not want to have this area swapped out, lock it */  vma->vm_flags |= VM_LOCKED;  if (remap_page_range(vma, vma->vm_start, offset, size, PAGE_SHARED))  {   printk("remap page range failed\n");   return - ENXIO;  }  return (0); } 
             | 
         
    
 
  remap_page_range函数的功能是构造用于映射一段物理地址的新页表,实现了内核空间与用户空间的映射,其原型如下:  
 
    
        
            | int remap_page_range(vma_area_struct *vma, unsigned long from, unsigned long to, unsigned long size, pgprot_tprot);  | 
         
    
 
  使用mmap最典型的例子是显示卡的驱动,将显存空间直接从内核映射到用户空间将可提供显存的读写效率。 
-- 原文链接: http://dev.yesky.com/412/2639912.shtml 
		    
                      
		      
		      
		   |