问题描述
我正在通过 realtek r8169 驱动程序,但有点卡在这条线上
tp->RxDescArray = dma_alloc_coherent(&pdev->dev,R8169_RX_RING_BYTES,&tp->RxPhyAddr,GFP_KERNEL);
从 Linux device driver 一书中,它只是说它是 ...Function handles both the allocation and the mapping of the buffer,...arguments are device structure and the size of buffer needed
这是什么意思:分配我可以理解,但mapping
这是否意味着我在 pdev 中所拥有的表示设备的 rx 描述符与从 dma_alloc_coherent
返回的内容相同,tp->RxDescArray
是作为软件对象的描述符? tp->RxDescArray 在驱动程序中属于 RxDesc
类型,如下所示
struct RxDesc {
__le32 opts1;
__le32 opts2;
__le64 addr;
};
如果这就是映射:意味着我在 pdev 中所拥有的物理设备上的设备 rx 描述符与我在软件对象 tp->RxDescArray
中拥有的相同,这就是映射的含义。那么谁定义了 RxDesc
的结构,这是否包含在数据表中。如果是,那么在哪个部分?数据表中有许多部分。应该更清楚
`
更新 也想知道这条线是做什么的
tp->RxDescArray[NUM_RX_DESC - 1].opts1 |= cpu_to_le32(RingEnd);
end
表示在该 end
地址之后的每个下一个将发生什么
更新 2
我需要有关是否有数据表的信息,例如来自英特尔 E1000E 驱动程序或来自 RealTek 的 r8169 驱动程序,然后我如何创建创建 Rx Descrptor 结构,在上面的代码中它执行类似的操作
struct RxDesc {
__le32 opts1;
__le32 opts2;
__le64 addr;
}
opts1、opts2 和 addr 是什么?这个驱动程序的作者是如何想到创建这个结构的。只有他有包含许多十六进制值的数据表
解决方法
DMA 访问由 IOMMU 转换,这在 Intel 系统上在 Intel® Virtualization Technology for Directed I/O (VT-d) specification 中描述。
函数 dma_alloc_coherent 分配内存并将映射引入 DMA 页表,以便设备可以访问内存。返回的地址不是内存的虚拟或物理地址,而是一个 I/O 虚拟地址 (IOVA),设备可以使用它来访问内存。当设备执行DMA时,IOVA由IOMMU翻译成物理内存地址。
IOMMU 可防止任何设备访问尚未映射到该特定设备的 I/O 地址空间的物理内存。
,RingEnd 标记 NIC 的环形缓冲区的结束。这样 NIC DMA 引擎就知道从哪里跳转到环形缓冲区的起始位置。