Linux mmap:在用户空间映射使用kmalloc分配的内核缓冲区
在用户空间进程中映射使用kmalloc分配的缓冲区的正确方法是什么?也许我还不了解内存映射…我写了一个内核模块,分配这个缓冲区(例如120字节),然后在用户空间进程中读写它。显然,我创建了一个char设备,并在Linux mmap:在用户空间映射使用kmalloc分配的内核缓冲区,linux,linux-kernel,linux-device-driver,mmap,Linux,Linux Kernel,Linux Device Driver,Mmap,在用户空间进程中映射使用kmalloc分配的缓冲区的正确方法是什么?也许我还不了解内存映射…我写了一个内核模块,分配这个缓冲区(例如120字节),然后在用户空间进程中读写它。显然,我创建了一个char设备,并在file\u operationsstruct中实现了mmap方法。我的方法是: static int my_mmap(struct file *filp, struct vm_area_struct *vma) { //printk(KERN_INFO "Allocated virt
file\u operations
struct中实现了mmap
方法。我的方法是:
static int my_mmap(struct file *filp, struct vm_area_struct *vma)
{
//printk(KERN_INFO "Allocated virtual memory length = %d", vma->vm_end - vma->vm_start);
long unsigned int size = vma->vm_end - vma->vm_start;
if (remap_pfn_range(vma, vma->vm_start,
__pa(mem_area) >> PAGE_SHIFT, //what about vma->vm_pgoff?
size,
vma->vm_page_prot) < 0)
return -EAGAIN;
vma->vm_flags |= VM_LOCKED;
vma->vm_ops = &vmops;
vma->vm_flags |= VM_RESERVED;
my_vm_open(vma);
return 0;
}
因此,只有当mem
与页面对齐时,mem\u区域
才包含相同的mem
值,否则应在下一页的开头包含指针。但是,如果我将此操作作为remap\u pfn\u range
的第三个参数传递,则值\u pa(mem\u area)>>PAGE\u SHIFT
映射效果良好。为什么?
谢谢大家!
vm->vm\u pgoff
是被映射设备内请求的偏移量-它是用户空间mmap()
调用的最后一个参数,从字节转换为页面。您可能正在查看mem
或kmem
mmap实现,在这种情况下,偏移量表示用户空间想要映射的物理或线性页面kmalloc()
分配的缓冲区内分配一个页面对齐的缓冲区。你最好使用\u get\u free\u pages()
,就像你已经猜测的那样,去掉中间人您应该测试映射的大小是否没有超过缓冲区。谢谢caf的支持!我仍然不理解第2点…我没有查看
mem
或kmem
实现,但我在Linux设备驱动程序手册中找到了它…现在我知道vma->vm\u pgoff
是被映射设备内的偏移量,但是如果我将remap\u pfn\u range
作为第三个参数vma->vmu pgoff
,则,我正在映射设备中的哪个内存?@caf我有一个类似的问题,但使用启动参数mmap:stackoverflow.com/q/12790382/143897?你能提供一些你的发现吗?谢谢。我有一个类似的问题,但是关于使用boot parammmap
:?你能提供一些你的发现吗?谢谢。这里的vm_operations_struct.fault不需要页面错误处理程序吗?最小可运行示例:
mem_area=(int *)(((unsigned long)mem + PAGE_SIZE - 1) & PAGE_MASK);