问题描述
LDD3(p:453)使用作为参数传入的缓冲区演示dma_map_single
.
LDD3 (p:453) demos dma_map_single
using a buffer passed in as a parameter.
bus_addr = dma_map_single(&dev->pci_dev->dev, buffer, count, dev->dma_dir);
第一季度:此缓冲区来自何处/何处?
Q1: What/where does this buffer come from?
kmalloc
?
第二季度:为什么DMA-API-HOWTO.txt指出我可以使用原始的kmalloc
进行DMA插入?
Q2: Why does DMA-API-HOWTO.txt state I can use raw kmalloc
to DMA into?
表格 http://www.mjmwired.net/kernel/Documentation/DMA-API- HOWTO.txt
L:74您不能使kmap()调用和DMA往返.
L:74 you cannot take the return of a kmap() call and DMA to/from that.
- 这样我可以将
kmalloc
返回的地址传递给我的硬件设备吗? - 还是我应该先在其上运行
virt_to_bus
? - 还是应该将其传递给
dma_map_single
?
- So I can pass the address returned from
kmalloc
to my hardware device? - Or should I run
virt_to_bus
on it first? - Or should I pass this into
dma_map_single
?
Q3 :完成DMA传输后,我可以通过kmalloc
地址读取内核驱动程序中的数据吗?
Q3: When the DMA transfer is complete, can I read the data in the kernel driver via the kmalloc
address?
addr = kmalloc(...);
...
printk("test result : 0x%08x\n", addr[0]);
第4季度:将其投放到用户空间的最佳方法是什么?
Q4: Whats the best way to get this to user-space?
-
copy_to_user
? - mmap kmalloc内存吗?
- 其他人?
推荐答案
-
kmalloc确实是获取缓冲区的一种来源.另一个可以是带有GFP_DMA标志的alloc_page.
kmalloc is indeed one source to get the buffer. Another can be alloc_page with the GFP_DMA flag.
的含义是,保证kmalloc返回的内存在物理内存中是连续的,而不仅仅是虚拟内存,因此您可以将该指针的总线地址提供给硬件.您确实需要在返回的地址上使用dma_map_single(),具体取决于确切的平台,然后不再是围绕virt_to_bus进行包装,或者可能要做的更多(然后设置IOMMU或GART表)
The meaning is that the memory that kmalloc returns is guaranteed to be contiguous in physical memory, not just virtual memory, so you can give the bus address of that pointer to your hardware. You do need to use dma_map_single() on the address returned which depending on exact platform might be no more then wrapper around virt_to_bus or might do more then do (set up IOMMU or GART tables)
正确,只需确保遵循DMA指南中说明的缓存一致性指南即可.
Correct, just make sure to follow cache coherency guidelines as the DMA guide explains.
copy_to_user可以正常工作,并且是最简单的答案.根据您的特定情况,可能就足够了,或者您可能需要性能更好的东西.您不能正常地将km分配的地址映射到用户空间,但是可以将DMA映射到用户提供的地址(有一些注意事项)或分配用户页面(使用GFP_USER的alloc_page)
copy_to_user will work fine and is the easiest answer. Depending on your specific case it might be enough or you might need something with better performance. You cannot normaly map kmalloced addresses to user space, but you can DMA into user provided address (some caveats apply) or allocate user pages (alloc_page with GFP_USER)
祝你好运!
这篇关于Linux内核设备驱动程序将DMA插入内核空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!