Memory management 如何在linux内核中将dma地址转换为虚拟地址?

Memory management 如何在linux内核中将dma地址转换为虚拟地址?,memory-management,linux-kernel,linux-device-driver,dma,Memory Management,Linux Kernel,Linux Device Driver,Dma,我正在编写PCI设备驱动程序,需要为DMA分配一些内存, 我正在使用这个函数: void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, int flag); 我将dma_句柄传递给设备 这个函数的返回值是一个我可以在内核中使用的虚拟地址,问题是我不想为每次内存分配保存这个地址 有没有办法将物理地址dma_句柄转换为我可以在内核中使用的地址? 类似于以下函数/宏之一: virt_to_pa

我正在编写PCI设备驱动程序,需要为DMA分配一些内存, 我正在使用这个函数:

void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, int flag);
我将dma_句柄传递给设备

这个函数的返回值是一个我可以在内核中使用的虚拟地址,问题是我不想为每次内存分配保存这个地址

有没有办法将物理地址dma_句柄转换为我可以在内核中使用的地址? 类似于以下函数/宏之一:

virt_to_page(kaddr)
page_to_pfn(page)
是否有phy到kvirt宏/函数或任何其他方式将物理地址转换为内核虚拟地址


谢谢

不,没有,dma\U句柄不仅仅是任何物理地址。从特定设备的角度来看,它是一个物理地址。不同总线上的不同设备对主存储器的看法可能完全不同。除此之外,返回的虚拟地址可以是动态映射的页面,而不是与主存的物理映射具有固定关系

内核结构中可能有足够的信息将某些总线和架构上的信息拼凑在一起,但不能保证,也不要期望它很快–内核自己的dma_free_coherent()要求您提供所有信息、虚拟地址、设备和dma_句柄来完成其工作,因为这是它能够跨体系结构和总线普遍工作的唯一方法


重申一下:dma_句柄本身是没有意义的。多个设备可能有完全相同的dma_句柄,但仍然指向不同的内存位置。

不,没有,dma_句柄不仅仅是任何物理地址。从特定设备的角度来看,它是一个物理地址。不同总线上的不同设备对主存储器的看法可能完全不同。除此之外,返回的虚拟地址可以是动态映射的页面,而不是与主存的物理映射具有固定关系

内核结构中可能有足够的信息将某些总线和架构上的信息拼凑在一起,但不能保证,也不要期望它很快–内核自己的dma_free_coherent()要求您提供所有信息、虚拟地址、设备和dma_句柄来完成其工作,因为这是它能够跨体系结构和总线普遍工作的唯一方法

重申一下:dma_句柄本身是没有意义的。多个设备可能具有完全相同的dma_句柄,该句柄仍然指向不同的内存位置