我希望将PFN与与dma_alloc_coherent一起分配的内存块关联起来,以便与PCIe设备一起使用,如下所示:
unsigned long pfn;
buffer = dma_alloc_coherent(&pcie->dev, size, &bus_addr, GFP_KERNEL);
// Get PFN?
virt_to_phys(buffer) >> PAGE_SHIFT;我知道这可能不是正确的方法,但它似乎有效.我只是在寻找正确的解决方案来将潜在的总线地址(因为我不知道是否有IOMMU)转换为PFN。提前谢谢。
注意:内核中似乎有一个名为dma_to_pfn的ARM函数,这似乎正是我所需要的,但是对于x86来说。
发布于 2020-01-21 22:05:35
你所做的确实是错误的。来自virt_to_phys()的手册页
此函数不为DMA传输提供总线映射。在几乎所有可能的情况下,设备驱动程序都不应该使用此功能。
DMA地址的等效函数是dma_to_phys(),在include/linux/dma-direct.h中定义如下:
phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);因此,你可以:
dma_to_phys(&pcie->dev, bus_addr) >> PAGE_SHIFT;请注意,我使用的是由bus_addr返回的dma_alloc_coherent(),而不是buffer,因为您显然需要将DMA地址(dma_addr_t)传递给此函数,而不是虚拟地址。
在PHYS_PFN()中定义了一个宏PFN,用于获取给定物理地址的PFN,如果您喜欢这样做的话:
PHYS_PFN(dma_to_phys(&pcie->dev, bus_addr));https://stackoverflow.com/questions/59847162
复制相似问题