Linux设备驱动之内存管理(4)

nopage
除了 remap_pfn_range()以外,在驱动程序中实现 VMA 的 nopage()函数通常可以为设备提供更加灵活的内存映射途径。当访问的页不在内存,即发生缺页异常时, nopage()会被内核自动调用。

static int xxx_mmap(struct file *filp, struct vm_area_struct *vma) { unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; if (offset >= _ _pa(high_memory) || (filp->f_flags &O_SYNC)) vma->vm_flags |= VM_IO; vma->vm_flags |= VM_RESERVED; /* 预留 */ vma->vm_ops = &xxx_nopage_vm_ops; xxx_vma_open(vma); return 0; } struct page *xxx_vma_nopage(struct vm_area_struct *vma, unsigned long address, int *type) { struct page *pageptr; unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; unsigned long physaddr = address - vma->vm_start + offset; /* 物理地址 */ unsigned long pageframe = physaddr >> PAGE_SHIFT; /* 页帧号 */ if (!pfn_valid(pageframe)) /* 页帧号有效? */ return NOPAGE_SIGBUS; pageptr = pfn_to_page(pageframe); /* 页帧号->页描述符 */ get_page(pageptr); /* 获得页,增加页的使用计数 */ if (type) *type = VM_FAULT_MINOR; return pageptr; /*返回页描述符 */ }

上述函数对常规内存进行映射, 返回一个页描述符,可用于扩大或缩小映射的内存区域。

由此可见, nopage()与 remap_pfn_range()的一个较大区别在于 remap_pfn_range()一般用于设备内存映射,而 nopage()还可用于 RAM 映射,其调用发生在缺页异常时。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/14646.html