小编典典
使用mmap方法从内核映射一组页面的最简单方法是使用故障处理程序来映射这些页面。基本上,您最终得到如下结果:
static int my_mmap(struct file *filp, struct vm_area_struct *vma)
{
vma->vm_ops = &my_vm_ops;
return 0;
}
static const struct file_operations my_fops = {
.owner = THIS_MODULE,
.open = nonseekable_open,
.mmap = my_mmap,
.llseek = no_llseek,
};
(其中其他文件操作是您的模块需要的)。另外,my_mmap您还可以执行任何范围检查等操作来验证mmap参数。
然后vm_ops看起来像:
static int my_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
vmf->page = my_page_at_index(vmf->pgoff);
get_page(vmf->page);
return 0;
}
static const struct vm_operations_struct my_vm_ops = {
.fault = my_fault
}
您只需要找出传递给您的故障功能的给定vma / vmf,即可将哪个页面映射到用户空间。这完全取决于模块的工作方式。例如,如果您做了
my_buf = vmalloc_user(MY_BUF_SIZE);
那么您使用的页面将类似于
vmalloc_to_page(my_buf + (vmf->pgoff << PAGE_SHIFT));
但是您可以轻松创建一个数组并为每个条目分配一个页面,无论使用什么,都可以使用kmalloc。
[只是注意到这my_fault是一个稍微有趣的功能名称]
2020-06-02