gpt4 book ai didi

linux - 如何将 Linux 内核缓冲区映射到用户空间?

转载 作者:IT王子 更新时间:2023-10-29 00:23:41 25 4
gpt4 key购买 nike

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

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

最佳答案

在 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 是一个有点有趣的函数名称]

关于linux - 如何将 Linux 内核缓冲区映射到用户空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10760479/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com