Linux kernel 从DMA地址(DMA地址)获取PFN?
我希望获得与分配有Linux kernel 从DMA地址(DMA地址)获取PFN?,linux-kernel,linux-device-driver,Linux Kernel,Linux Device Driver,我希望获得与分配有dma\u alloc\u coherent的内存块相关联的PFN,以便与PCIe设备一起使用,如下所示: 无符号长pfn; buffer=dma\u alloc\u相干(&pcie->dev,size,&bus\u addr,GFP\u内核); //得到PFN? 虚拟至物理(缓冲区)>>页面移位; 我知道这可能不是正确的方法,但它似乎有效。。。我只是在寻找将潜在的总线地址(因为我不知道是否有IOMMU)转换为PFN的正确解决方案。提前谢谢 注意:内核中似乎有一个ARM函数名
dma\u alloc\u coherent
的内存块相关联的PFN,以便与PCIe设备一起使用,如下所示:
无符号长pfn;
buffer=dma\u alloc\u相干(&pcie->dev,size,&bus\u addr,GFP\u内核);
//得到PFN?
虚拟至物理(缓冲区)>>页面移位;
我知道这可能不是正确的方法,但它似乎有效。。。我只是在寻找将潜在的总线地址(因为我不知道是否有IOMMU)转换为PFN的正确解决方案。提前谢谢
注意:内核中似乎有一个ARM函数名为
dma\u to\u pfn
,这似乎正是我所需要的,但对于x86而言。您所做的确实是错误的。从手册页中:
此函数不提供DMA传输的总线映射。在几乎所有可能的情况下,设备驱动程序都不应该使用此功能
DMA地址的等效函数在include/linux/DMA direct.h
中定义如下:
phys\u-addr\u-dma\u-to\u-phys(结构设备*dev,dma\u-addr\t-daddr);
因此,您可以:
dma到物理系统(&pcie->dev,bus\u addr)>>PAGE\u SHIFT;
请注意,我使用的是由dma\u alloc\u coherent()
返回的bus\u addr
,而不是缓冲区
,因为您显然需要将dma地址(dma\u addr\u t
)传递给此函数,而不是虚拟地址
include/linux/pfn.h
中似乎还定义了一个宏来获取给定物理地址的pfn,如果您愿意使用该宏:
PHYS-PFN(dma-to-PHYS(&pcie->dev,bus-addr));
我认为正确的方法是通过PFNs进行遍历并比较必要的信息。请问你为什么需要这个?是的,IOMMU可能会做一些有趣的事情,但这些事情不允许您执行上述操作(例如,当使用反弹缓冲区时)。