Linux mmap:在用户空间映射使用kmalloc分配的内核缓冲区

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

在用户空间进程中映射使用kmalloc分配的缓冲区的正确方法是什么?也许我还不了解内存映射…我写了一个内核模块,分配这个缓冲区(例如120字节),然后在用户空间进程中读写它。显然,我创建了一个char设备,并在
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 param
    mmap
    :?你能提供一些你的发现吗?谢谢。这里的vm_operations_struct.fault不需要页面错误处理程序吗?最小可运行示例:
    mem_area=(int *)(((unsigned long)mem + PAGE_SIZE - 1) & PAGE_MASK);