Linux下的DMA和I / O内存区域
我写这篇文章是因为我对DMA的行为有些怀疑.
我正在阅读PCI布局以及设备驱动程序如何与卡交互,我读到了有关DMA的信息. 由于我的理解,PCI卡没有DMA控制器,而不是他们要求成为总线的主控制器,然后他们能够获取DMA地址并在存储器和设备之间进行传输(通过总线). 这个DMA地址是RAM的一部分,实际上它是一个物理地址,在无所事事之前你需要将它转换成你的驱动程序可以使用的东西,比如内核虚拟内存. /* Virtual kernel address */ kernel_buff = pci_alloc_consistent(dev,PAGE_SIZE,&dma_addr); pr_info("Kernel buffer - %12p,Dma_addr - %12pn",kernel_buff,(void *)dma_addr ); pr_info( "Kernelbuffer - dma_addr - %12pn",kernel_buff - dma_addr); strcpy(kernel_buff,"Test dman"); /* Test memory */ ptest = (void *)dma_addr; ptest = phys_to_virt((unsigned long)ptest); pr_info("Ptest virtual memory(%p) containts - %sn",ptest,(char *)ptest); 输出是: [425971.835669] Kernel buffer - ffff8800ca70a000,Dma_addr - ca70a000 [425971.835671] Kernelbuffer - dma_addr - ffff880000000000 [425971.835673] Ptest virtual memory(ffff8800ca70a000) containts - Test dma 这就是我理解DMA是RAM的一部分的方式. 我怀疑这种转移是如何进行的. 这是关于DMA的. 关于I / O内存映射: 当我们请求设备的I / O内存区域时,例如: pci_resource_start 我们要求设备寄存器所在的存储区域? 最后一点是,我们使用DMA,因为I / O内存映射每个周期只允许几个字节,因为这个过程涉及CPU,对吗? 解决方法
将数据传输到设备所涉及的步骤可归纳如下:
1.假设您将数据放在缓冲区中. 你有它..数据被传输到设备! 现在来讨论有关IO内存映射的问题: 首先,当我们调用pci_resource_start()时,我们不会“请求”IO端口.这是我们收集信息的方式.关于港口.请求使用pci_request_regions()完成.具体到您的问题: 我们要求设备寄存器所在的存储区域? 使用它,我们要求内核访问设备寄存器所在的内存区域(内存映射端口). 那么这样我们将这个内存位置放入RAM中? 不,我们在RAM中没有这个内存位置,它只是内存映射,这意味着设备与RAM共享相同的地址,数据和控制线,因此,用于访问RAM的相同指令也可以是用于访问设备寄存器. 你自己回答了你的上一个问题. DMA为要有效传输的数据提供了大量资金.但是,有些情况下您需要使用内存映射来传输数据.在DMA事务处理的说明中已经说明了最好的例子,您需要将地址和控制信息传输到设备.这只能通过内存映射IO来完成. 希望这可以帮助. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |