Linux内核设备驱动程序将DMA转换为内核空间

时间:2011-04-06 09:39:52

标签: linux linux-kernel linux-device-driver dma

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

  

L:51如果您通过页面分配器kmalloc()获取了内存,那么您可以使用这些例程返回的地址与该内存进行DMA交换。

     

L:74你不能将kmap()调用和DMA返回到/来自。

  1. 我可以将kmalloc返回的地址传递给我的硬件设备吗?
  2. 或者我应该首先运行virt_to_bus吗?
  3. 或者我应该将其传递给dma_map_single
  4. Q3 :DMA传输完成后,我可以通过kmalloc地址读取内核驱动程序中的数据吗?

    addr = kmalloc(...);
    ...
    printk("test result : 0x%08x\n", addr[0]);
    

    Q4 :将这个用户空间送到用户空间的最佳方法是什么?

    1. copy_to_user
    2. mmap kmalloc memory?
    3. 他人?

1 个答案:

答案 0 :(得分:16)

  1. kmalloc确实是获取缓冲区的一个来源。另一个可以是带有GFP_DMA标志的alloc_page。

  2. 意思是kmalloc返回的内存保证在物理内存中连续,而不仅仅是虚拟内存,因此您可以将该指针的总线地址提供给您的硬件。你需要在返回的地址上使用dma_map_single(),这取决于确切的平台可能不再是virt_to_bus的包装,或者可以做更多的事情(设置IOMMU或GART表)

  3. 正确,只需确保遵循缓存一致性指南,如DMA指南所述。

  4. copy_to_user可以正常工作,是最简单的答案。根据您的具体情况,它可能就足够了,或者您可能需要具有更好性能的东西。您不能正常地将kmalloced地址映射到用户空间,但您可以DMA到用户提供的地址(一些警告适用)或分配用户页面(alloc_page with GFP_USER)

  5. 祝你好运!