0
votes

I have a typical V4L2 driver that I use configured for memory mapped IO method. This driver hands off a virtual address to my user space app. All of this is working fine.

I have another driver that expects as input a kernel physical address. I want to connect the output of the V4L2 driver to the input of this driver but it needs a physical address (this driver controls FPGA functionality).

My understanding is that the kernel routine: virt_to_phys() routine will NOT work with DMA allocated memory mapped addresses. Is this true? If so, how do I get the physical address from the DMA memory mapped V4L2 virtual address that was passed into user space?

I am just hacking up a proof of concept thing here so hard coding some addresses is not an issue. This is the sole application running on a dedicated embedded platform.

Thanks, -Andres

1
The V4L2 driver is creating a virtual address for user space. That means this driver already has a physical address (you must know the physical address in order to set this mapping up). Go look at the driver source and see how it's obtaining the address prior to creating the virtual address mapping for it. I guess it probably comes from a PCI device's BAR register (which lspci would show you). Technically, you can also chase down the page table entries assigned to the user process' mapping and read back the address stored there but that would be the more difficult way to get it.Gil Hamilton

1 Answers

1
votes

This can be explained in 3 steps:

  1. V4L2 application will call VIDIOC_REQBUF to allocate a buffer. If memory type is VB2_MEMORY_MMAP. V4l2 framework driver will allocate buffer and pack it as vb2_dc_buf structure type and store this structure pointer in planes[plane].mem_priv. This structure will have DMA physical address.

  2. Application has to call VIDIOC_EXPBUF by passing planes[plane].mem_priv. Then v4l2 framework implements vb2_core_expbuf() where it invokes DMA specific APIs like vb2_dc_get_dmabuf() and dma_buf_fd() to get DMA buffer fd.

  3. Application can export this (pass this fd) to 2nd driver where the 2nd driver will import fd and convert back to DMA physical address using DMA APIs