根据 Linux Device Drivers 这本书的作者所说:必须确保操作系统和硬件之间的 DMA 地址映射范围应该相等
在尝试 DMA 之前必须回答的第一个问题是给定设备在当前主机上能够执行此类操作的位置
从 Kernel.org 它说,流映射的设置的第一步是通过调用
int dma_set_mask(struct device *dev, u64 mask);
DMA 相干映射/一致分配的第一步是通过调用执行的
to dma_set_coherent_mask()
在 E1000E 驱动程序和 RealTek 驱动程序中都这样做,因为它们在 pci 驱动程序的探测函数中使用此函数调用
dma_set_mask_and_coherent
用于流式传输和连贯映射,通知内核硬件支持的位掩码64
这就是 RealTek 设备驱动程序启用 DMA 映射的方式
dma_alloc_coherent(&pdev->dev, R8169_RX_RING_BYTES,
&tp->RxPhyAddr, GFP_KERNEL);
net_device 的 open 函数内部
对于流式 DMA 映射,这使用
alloc_pages_node // allocating Kernel page for DMA
dma_map_page(d, data, 0, R8169_RX_BUF_SIZE, DMA_FROM_DEVICE); //Enabling Streaming mappingg?
也在开放功能中
我的问题是为什么 DMA 有两个映射,为什么真正的驱动程序同时使用 Streaming 和 Coherent 映射?
就像在 RealTek 设备中一样,它只使用单页流映射加上相干映射,所以基本上它的连接 Rx 描述符数组由指针表示,具有相干映射和连接到它称为 Rx_databuff[256U] 类型的数组的页面流映射page *