在用户空间进程中映射使用kmalloc分配的缓冲区的正确方法是什么?也许我还没有理解内存映射......我编写了一个内核模块来分配这个缓冲区(例如120字节),我会在用户空间进程中读取和写入它.显然我创建了一个char设备并mmap在file_operationsstruct中实现了一个方法.我的方法是:
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;
}
Run Code Online (Sandbox Code Playgroud)
其中,mem_area在与分配的内存区域指向kmalloc在模块初始化.该区域填充相同的值(例如0x10).一切正常,但我认为这段代码有问题:
kmalloc可以返回一个非页面对齐的指针,在这种情况下,我认为不正确的第三个参数的值remap_pfn_range实际上在用户空间中我读错了值.相反,如果我使用__get_free_page(因为该函数总是返回kmalloc页面对齐的指针)或返回页面对齐指针时所有工作.内存映射适用于多个内存区域PAGE_SIZE,如果我分配整个页面而不是使用kmalloc?
什么时候my_mmap调用,内核已经分配了一些页面呢?我问这个,因为我发现定制的一些实现 …
我有一个Linux设备驱动程序,它接口到一个理论上可以使用64位地址执行DMA的设备.我想测试看看这实际上是否有效.
有没有一种简单的方法可以强制Linux机器不使用物理地址4G以下的任何内存?如果内核映像处于低内存状态,则可以.我只是希望能够强制我知道所有动态分配的缓冲区的情况,并且为我分配的任何内核或用户缓冲区都不能以32位进行寻址.这是一种蛮力,但比我能想到的任何其他东西都更全面.
这应该有助于我捕获(1)未正确配置或加载完整地址(或只是简单破坏)的硬件,以及(2)意外和不必要地使用反弹缓冲区(因为无处可跳转).
澄清:我正在运行x86_64,所以我不关心大多数旧的32位寻址问题.我只想测试驱动程序是否可以使用64位物理地址正确连接大量缓冲区.