我构建了一个字符驱动程序,我在其中使用
dma_alloc_coherent()
分配了两个 PAGESIZE 缓冲区
现在我使用
ioctl()
作为source_offset
和dest_offset< 将这些 BUFFER [src_ptr & dest_ptr] 的物理地址传递给用户空间
.在用户空间中,此偏移量用作 mmap 调用的偏移量。 所以在同一个/dev 文件上说/dev/250 我正在进行两个 MMAP 调用
usr_src_ptr= mmap(0,page_size, PROT_READ|PROT_WRITE, MAP_SHARED,dev_FD, src_offset ); if (usr_src_ptr == MAP_FAILED){ printf("USR[UPP]:SOURCE MMAP FAiled \n\n"); close(dev_FD); exit(-1); }else{ printf("USR[UPP]:SOURCE MMAP is %X..\n",usr_src_ptr); } usr_dest_ptr= mmap(0,page_size, PROT_READ|PROT_WRITE,MAP_SHARED, dev_FD,dest_offset ); if (usr_dest_ptr == MAP_FAILED){ printf("USR[UPP]:DEST MMAP FAiled \n\n"); close(dev_FD); exit(-1); }else{ printf("USR[UPP]:DEST MMAP is %X..\n",usr_dest_ptr); }
我在用户空间的
user_src_ptr
中写入0x77
并打印user_src_ptr
在用户空间,dest_src_ptr
在 KERNEL 空间。 我获得了用户空间和内核空间的正确数据我正在内核空间的
dest_ptr
中写入0x55
并打印dest_ptr
在内核空间和usr_dest_ptr
在用户空间。 现在对于这种情况,我得到了正确的数据,例如内核缓冲区中的0X55
dest_ptr
,但目标的用户空间缓冲区总是 返回0x77
。即我写入usr_src_ptr
的数据。
如果我们可以在不同的 OFFSET 上对同一个文件执行两个 mmap()
操作,谁能告诉我吗?
代替:
if ((ret = remap_pfn_range(vma,vma->vm_start,
(virt_to_phys((void *)src_ptr) >> PAGE_SHIFT),
size,vma->vm_page_prot)) < 0) return ret;
正确的是:
if ((ret = remap_pfn_range(vma,vma->vm_start,
vma->vm_pgoff,
size,vma->vm_page_prot)) < 0)
感谢 BЈовић 的输入....
最佳答案
是的,正如您已经在示例中发现的那样,您可以在同一进程中对具有不同偏移量的同一文件执行 mmap()。 man page for mmap(2)没有提到偏移量限制(除了它必须是 sysconf(_SC_PAGE_SIZE) 返回的页面大小的倍数,当然它不应该超出文件范围)。
只有one limit : 当 mmap()-ing 在一个进程中使用相同的文件时,您必须使用相同的文件 ID。你在你的例子中这样做了,这就是它工作正常的原因。
关于linux - 我们可以在同一个/dev 文件上使用两个 MMAP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14581968/