int mapdrv_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 (offset & ~PAGE_MASK) { printk("offset not aligned: %ld\n", offset); return -ENXIO; } if (size > MAPLEN) { printk("size too big\n"); return -ENXIO; } /* only support shared mappings. */ if ((vma->vm_flags & VM_WRITE) && !(vma->vm_flags & VM_SHARED)) { printk("writeable mappings must be shared, rejecting\n"); return -EINVAL; } /* do not want to have this area swapped out, lock it */ vma->vm_flags |= VM_LOCKED; if (offset == 0) { vma->vm_ops = &map_vm_ops; //必须主动打开vma map_vopen(vma); } else { printk("offset out of range\n"); return -ENXIO; } return 0; }
static int mapdrv_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 (offset + size > MAPLEN) { printk("size too big\n"); return -ENXIO; } /* only support shared mappings. */ if ((vma->vm_flags & VM_WRITE) && !(vma->vm_flags & VM_SHARED)) { printk("writeable mappings must be shared, rejecting\n"); return -EINVAL; } /* do not want to have this area swapped out, lock it */ vma->vm_flags |= VM_LOCKED; vma->vm_ops = &map_vm_ops; /* call the open routine to increment the usage count */ map_vopen(vma); return 0; }