Драйвер устройства ядра Linux для DMA с устройства в память пользовательского пространства

Я хочу получать данные из включенного DMA, Аппаратное устройство PCIe в пользовательское пространство как можно быстрее.

Q: Как мне объединить «прямой ввод-вывод в пользовательское пространство с / и / через передачу DMA»

  1. Читая через LDD3, кажется, что я нужно выполнить несколько разных типов операций ввода-вывода !?

    dma_alloc_coherent дает мне физический адрес, который я могу передать аппаратному устройству. Но для этого потребуется настроить get_user_pages и выполнить вызов типа copy_to_user после завершения передачи. Это кажется пустой тратой - просить устройство выполнить DMA в память ядра (действуя как буфер), а затем снова передать его в пользовательское пространство. LDD3 p453: / * Только теперь можно безопасно обращаться к буферу, копировать для пользователя и т. Д. * /

  2. В идеале мне нужна некоторая память, которую:

    • Я могу использовать в пользовательском пространстве (Возможно запросить драйвер с помощью вызова ioctl для создания памяти / буфера, доступной для DMA?)
    • Я могу получить физический адрес для передачи на устройство, так что все, что нужно сделать в пользовательском пространстве, - это выполнить чтение драйвера
    • метод чтения активирует передачу DMA, блокирует ожидание завершения прерывания DMA и после этого освобождает чтение пользовательского пространства (теперь пользовательское пространство безопасно для использования / чтения памяти).

Нужны ли мне отображения одностраничной потоковой передачи, сопоставление настроек и буферы пользовательского пространства, сопоставленные с get_user_pages dma_map_page ?

Мой код до сих пор устанавливает get_user_pages по заданному адресу из пользовательского пространства (я называю это Часть прямого ввода / вывода). Потом, dma_map_page со страницей из get_user_pages . Я даю устройству возвращаемое значение из dma_map_page в качестве физического адреса передачи DMA.

Я использую некоторые модули ядра в качестве ссылки: drivers_scsi_st.c и drivers-net -sh_eth.c . Я бы посмотрел на код Infiniband, но не могу найти самый простой!

Заранее большое спасибо.

30
задан Jorge Bellon 11 August 2017 в 16:02
поделиться