如何获取V4L2 DMA虚拟地址的物理地址?

how to get physical address of V4L2 DMA virtual address?

我有一个典型的 V4L2 驱动程序,我使用它配置内存映射 IO 方法。该驱动程序将虚拟地址交给我的用户 space 应用程序。所有这些都工作正常。

我有另一个驱动程序需要内核物理地址作为输入。我想将 V4L2 驱动程序的输出连接到该驱动程序的输入,但它需要一个物理地址(该驱动程序控制 FPGA 功能)。

我的理解是内核例程:virt_to_phys() 例程不适用于 DMA 分配的内存映射地址。这是真的?如果是这样,我如何从传递给用户的 DMA 内存映射 V4L2 虚拟地址中获取物理地址 space?

我只是在这里进行概念验证,因此对某些地址进行硬编码不是问题。这是专用嵌入式平台上唯一的应用程序 运行。

谢谢, -安德烈斯

这可以通过 3 个步骤来解释:

  1. V4L2 应用程序将调用 VIDIOC_REQBUF 分配缓冲区。如果内存类型是VB2_MEMORY_MMAP。 V4l2框架驱动会分配buffer并将其打包为vb2_dc_buf结构类型,并将该结构指针存储在planes[plane].mem_priv中。此结构将具有 DMA 物理地址。

  2. 应用程序必须通过传递平面[plane].mem_priv 来调用VIDIOC_EXPBUF。然后 v4l2 框架实现 vb2_core_expbuf() ,它调用 DMA 特定的 API,如 vb2_dc_get_dmabuf() 和 dma_buf_fd() 来获取 DMA 缓冲区 fd.

  3. 应用程序可以将此导出(传递此 fd)到第二个驱动程序,其中第二个驱动程序将导入 fd 并使用 DMA API 转换回 DMA 物理地址