Я хочу как можно быстрее получить данные с аппаратного устройства PCIe с поддержкой DMA в пользовательское пространство.
В: Как мне объединить «прямой ввод-вывод в пользовательское пространство с / и / через передачу DMA»
Читая LDD3, мне кажется, что мне нужно выполнить несколько разных типов операций ввода-вывода !?
dma_alloc_coherent
дает мне физический адрес, который я могу передать аппаратному устройству. Но потребуется настроитьget_user_pages
и выполнить вызов типаcopy_to_user
после завершения передачи. Это кажется пустой тратой - просить устройство выполнить DMA в память ядра (действуя как буфер), а затем снова передать его в пользовательское пространство. LDD3 p453:/* Only now is it safe to access the buffer, copy to user, etc. */
В идеале мне нужно немного памяти, которая:
- I can use in user-space (Maybe request driver via a ioctl call to create DMA'able memory/buffer?)
- Я могу получить физический адрес для передачи на устройство, так что все, что нужно сделать в пользовательском пространстве, - это выполнить чтение драйвера.
- метод чтения активирует передачу 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, но не могу найти, какой из них самый простой!
Спасибо заранее.