2017-06-21 206 views
1

我和朋友正试图为高级操作系统类编写虚拟设备的设备驱动程序(读取:不是PCI或USB)。我们正在使用Ubuntu 16.04。我们的任务是在我们的驱动程序中调用IOCTL并为它提供一个完整的RGB值(一个整数数组),一个空目标缓冲区和一个长度的源缓冲区。我们将调用DMA控制器将源缓冲区的内容传输到目标缓冲区,然后对目标缓冲区中的值应用线性转换。是否可以在Linux中进行内存到内存的DMA传输?如果是这样,什么函数调用DMA来开始传输?

我们已经成功地完成了没有DMA的转换,并且我们已经成功地为我们的设备分配了DMA通道。我们遇到的问题是我们似乎无法找到任何地方的功能,它描述了使用DMA启动传输。我们希望在完成后引发中断(驱动程序不应该等待传输完成)。

为了清楚我们要求的内容,我们只想知道在哪里可以找到描述此过程的函数的定义。我们不是要求代码或完成此任务的确切方法;我们只想知道可以使用哪些函数和/或什么头文件来查找它们。我们已经通过linux/dma-mapping.h查看了看起来令人难以置信的内容。我们也研究了LDD3一段时间,但似乎完全通过建立DMA的过程,而没有提供关于实际开始DMA传输的函数的信息。

回答

1

有在最近的Linux内核,支持能够存储到内存复制本地DMA引擎在drivers/dma目录“DMA引擎”的API,检查它们是如何实现的:

http://elixir.free-electrons.com/linux/latest/source/drivers/dma/Kconfig

menuconfig DMADEVICES 
bool "DMA Engine support" 
depends on HAS_DMA 
help 
    DMA engines can do asynchronous data transfers without 
    involving the host CPU. Currently, this framework can be 
    used to offload memory copies in the network stack and 
    RAID operations in the MD driver. This menu only presents 
    DMA Device drivers supported by the configured arch, it may 
    be empty in some cases. 

DMA引擎在多个硬件平台上实现,但不是在每台PC或服务器或SoC中实现。检查Kconfig中的选项,如INTEL_IDMA64“英特尔集成DMA ..英特尔Skylake PCH”,INTEL_IOATDMA“英特尔(R)I/OAT DMA引擎,出现在最新的英特尔至强芯片组中。

其他选项是使用一些虚拟化平台(如qemu)并实现您自己的设备仿真(https://stackoverflow.com/a/44612957 edu设备和simple driver,http://wiki.qemu.org/Features/QOM)。

如果你问如何登记中断处理程序,告诉我们什么是你的(虚拟)总线,你的(虚拟)设备的连接方式(以及如何你没有实现虚拟设备)。和qemu's "edu" pci.c driver has some examples for PCI-compatible interruptsrequest_irq(pci_irq, irq_handler, IRQF_SHARED, "pci_irq_handler0", &major)

相关问题