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 声明我可以使用 rawkmalloc
DMA 进入?
Form http://www.mjmwired.net/kernel/Documentation/DMA-API-HOWTO.txt http://www.mjmwired.net/kernel/Documentation/DMA-API-HOWTO.txt
L:51 如果您通过页面分配器 kmalloc() 获取了内存,那么您可以使用从这些例程返回的地址与该内存进行 DMA 传输。
L:74 你不能从 kmap() 调用和 DMA 中获取返回值。
- 这样我就可以传递从返回的地址
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 内存?
- others?
kmalloc 确实是获取缓冲区的来源之一。另一个可以是带有 GFP_DMA 标志的 alloc_page。
含义是 kmalloc 返回的内存保证在物理内存中是连续的,而不仅仅是虚拟内存,因此您可以将该指针的总线地址提供给您的硬件。您确实需要在返回的地址上使用 dma_map_single() ,根据具体平台,该地址可能不再是 virt_to_bus 的包装器,或者可能执行更多操作(设置 IOMMU 或 GART 表)
正确,只需确保遵循 DMA 指南所解释的缓存一致性准则即可。
copy_to_user 可以正常工作,并且是最简单的答案。根据您的具体情况,这可能就足够了,或者您可能需要性能更好的东西。通常,您无法将 kmalloced 地址映射到用户空间,但您可以 DMA 到用户提供的地址(需要注意一些)或分配用户页面(带有 GFP_USER 的 alloc_page)
祝你好运!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)