我正在开发一个 linux 设备驱动程序,我需要了解如何访问用户分配的内存区域。详细来说,对于一个 32 字节的缓冲区,用户调用:
void *UserAddr;
posix_memalign(&UserAddr, getpagesize(), 32); //allocation of the page-alligned buffer
memset(UserAddr, 0x55, 32); //just to see if the data in the buffer is correct
ioctl(fd, MAP_BUFFER, UserAddr); //call kernel module
现在,在内核模块 ioctl 中,我需要 phys 地址将其传递给 pci 设备以进行 DMA 操作。我目前正在做的是(此示例仅适用于 1 页,以了解它是否正确):
if(!access_ok(VERIFY_READ,(char *)user_address,32*sizeof(u32)))
goto error1;
down_read(¤t->mm->mmap_sem);
if(get_user_pages(current, current->mm,(unsigned long)user_address,1,1,0,pages_list,NULL)<1)
goto error2;
up_read(¤t->mm->mmap_sem);
phys_addr=pci_map_page(dev,pages_list[0],0,PAGE_SIZE,DMA_BIDIRECTIONAL);
代码工作正常,但我的问题是:
- 谁在“固定”页面?或者我必须明确调用 SetPageReserved(pages_list[0])?
- 当我完成使用缓冲区时,它如何用于发布?pci_unmap 仅此而已?即使我调用了 SetPageReserved?
- 一般来说,在用户空间地址上调用 virt_to_phys 是否安全(如果页面被固定)?(或 virt_to_bus 在 DMA 的情况下)
- 这是访问用户空间缓冲区的“最佳实践”吗?