LDD3(p:453)使用传入的缓冲区作为参数来演示dma_map_single

bus_addr = dma_map_single(&dev->pci_dev->dev, buffer, count, dev->dma_dir);
Q1 :此缓冲区来自何处?kmalloc
Q2 :为什么DMA-API-HOWTO.txt指出我可以使用原始kmalloc将DMA插入?
表格http://www.mjmwired.net/kernel/Documentation/DMA-API-HOWTO.txt

  • 那么我可以将kmalloc返回的地址传递给我的硬件设备吗?
  • 还是我应该先在上面运行virt_to_bus
  • 还是应该将其传递给dma_map_single

  • Q3 :完成DMA传输后,我可以通过kmalloc地址读取内核驱动程序中的数据吗?
    addr = kmalloc(...);
    ...
    printk("test result : 0x%08x\n", addr[0]);
    
    Q4 :将其带到用户空间的最佳方法是什么?
  • copy_to_user吗?
  • mmap kmalloc内存?
  • 其他人?
  • 最佳答案

  • kmalloc确实是获取缓冲区的一种来源。另一个可以是带有GFP_DMA标志的alloc_page。
  • 的含义是,确保kmalloc返回的内存在物理内存中是连续的,而不仅仅是虚拟内存,因此您可以将该指针的总线地址提供给硬件。您确实需要在返回的地址上使用dma_map_single(),具体取决于确切的平台,而不再是然后围绕virt_to_bus进行包装,或者可能会做更多然后做(设置IOMMU或GART表)
  • 正确,请确保遵循DMA指南中说明的缓存一致性指南。
  • copy_to_user可以正常工作,并且是最简单的答案。根据您的具体情况,可能就足够了,或者您可能需要性能更好的东西。您不能正常地将km分配的地址映射到用户空间,但可以将DMA映射到用户提供的地址(有一些注意事项)或分配用户页面(使用GFP_USER的alloc_page)

  • 祝好运!

    07-25 23:42
    查看更多