Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux kernel 从DMA地址(DMA地址)获取PFN?_Linux Kernel_Linux Device Driver - Fatal编程技术网

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可能会做一些有趣的事情,但这些事情不允许您执行上述操作(例如,当使用反弹缓冲区时)。