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

查看:26
本文介绍了如何将 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天全站免登陆