如何将Linux内核缓冲区映射到用户空间? [英] How to mmap a Linux kernel buffer to user space?

查看:408
本文介绍了如何将Linux内核缓冲区映射到用户空间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

比方说,缓冲区是使用基于页面的方案分配的.一种实现mmap的方法是使用remap_pfn_range,但LDD3表示这不适用于常规内存.看来我们可以通过使用SetPageReserved标记保留的页面来解决此问题,以便将其锁定在内存中.但是不是所有内核内存都已经不可交换了,即已经保留了吗?为什么需要显式设置保留位?

Let's say the buffer is allocated using a page based scheme. One way to implement mmap would be to use remap_pfn_range but LDD3 says this does not work for conventional memory. It appears we can work around this by marking the page(s) reserved using SetPageReserved so that it gets locked in memory. But isn't all kernel memory already non-swappable i.e. already reserved? Why the need to set the reserved bit explicitly?

这与从HIGH_MEM分配的页面有关吗?

Does this have something to do with pages allocated from HIGH_MEM?

推荐答案

在mmap方法中从内核映射一组页面的最简单方法是使用故障处理程序来映射页面.基本上,您最终得到的像是这样:

The simplest way to map a set of pages from the kernel in your mmap method is to use the fault handler to map the pages. Basically you end up with something like:

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参数.

(where the other file operations are whatever your module needs). Also in my_mmap you do whatever range checking etc. is needed to validate the mmap parameters.

然后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,即可将哪个页面映射到用户空间.这完全取决于模块的工作方式.例如,如果您这样做

where you just need to figure out for a given vma / vmf passed to your fault function which page to map into userspace. This depends on exactly how your module works. For example, if you did

my_buf = vmalloc_user(MY_BUF_SIZE);

然后您使用的页面将类似于

then the page you use would be something like

vmalloc_to_page(my_buf + (vmf->pgoff << PAGE_SHIFT));

但是您可以轻松地创建一个数组并为每个条目分配一个页面,使用kmalloc进行任何操作.

But you could easily create an array and allocate a page for each entry, use kmalloc, whatever.

[只是注意到my_fault是一个函数的稍微有趣的名称]

[just noticed that my_fault is a slightly amusing name for a function]

这篇关于如何将Linux内核缓冲区映射到用户空间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆