我正在在ARM上有无SMMU的情况下对DMA流进行实验。 我们的自定义应用程序需要内核地址,物理地址和总线地址。
启用SMMU后,我设法使用dma_alloc_coherent()
获取了内核地址和总线地址,但无法通过virt_to_phys()
获取物理地址。
这使我将dma_alloc_coherent()
替换为dma_map_single
如下:
// Get kernel address
res->KernelAddress = (u64)kzalloc( size , GFP_KERNEL | GFP_DMA);
// Get bus address
res->BusAddress = (u64)dma_map_single(&DevExt->pdev->dev, &res->KernelAddress, size, PCI_DMA_BIDIRECTIONAL);
// Get physical address
res->PhysicalAddress = (u64)virt_to_phys( (void*)res->KernelAddress );
dma_sync_single_for_cpu(&DevExt->pdev->dev, res->BusAddress, size, PCI_DMA_BIDIRECTIONAL);
// Map physical address to virtual address in user space
if (remap_pfn_range(vma, vma->kern_addr, vma->phys_addr,size,vma->vm_page_prot));
上述流程没有问题。 我设法获得3个地址,但DMA写入返回的位置失败。 要使上述流程正常工作,还需要其他DMA API吗?
最好共享任何代码段!