2013-02-19 3 views
2

У меня есть несколько необычная ситуация, когда я разрабатываю модуль моделирования для устройства Ethernet. В идеале, уровень моделирования будет просто идентичен реальному оборудованию в отношении набора регистров. Проблема, с которой я столкнулся, заключается в том, что регистры DMA в аппаратном обеспечении загружаются с помощью DMA-сопоставления (физического) адреса данных. Мне нужно использовать эти физические адреса для копирования данных из буфера Tx на исходном устройстве в буфер Rx на целевом устройстве. Для этого в модульном коде мне нужны указатели на виртуальную память. Я посмотрел на phys_to_virt(), и я не понимаю, этот комментарий на странице человека:Преобразование сопоставления DMA в виртуальный адрес

This function does not handle bus mappings for DMA transfers. 

Означает ли это, что физический адрес, который извлекается с помощью dma_map_single не может быть преобразован обратно в виртуальный адрес, используя phys_to_virt() ? Есть ли другой способ сделать это преобразование?

ответ

0

Нет общего способа сопоставления адреса DMA с виртуальным адресом. Функция dma_map_single() может программировать IOMMU (например, VT-d в системе Intel x86), что приводит к тому, что адрес DMA полностью не связан с исходным физическим или виртуальным адресом. Однако this presentation и связанные слайды дают один подход к подключению эмулируемой аппаратной модели до реального драйвера (в основном, использование виртуализации).

+0

Спасибо за ссылку на слайды. Я взгляну. – jhd1013

0

Я не слишком разбираюсь в этом вопросе, но если вы используете "phys_to_virt()", возможно, причина, по которой этот адрес, доступный на шине, не может быть закрыт виртуальной функцией. Я не уверен, просто попробуйте bus_to_virt(bus_addr);function

+0

Спасибо, что постарался ответить. Оказывается, мой оригинальный вопрос не имеет особого смысла. Поскольку я пытаюсь имитировать оборудование, под ним нет реальной шины. Без какой-либо шины под ядром для сопоставления я бы не получил адрес DMA для начала. – jhd1013

0

Попробуйте dma_virt = virt_to_phys(bus_to_virt(dma_handle))

он работал для меня. Он дает тот же виртуальный адрес, который был отображен dma_coherent_alloc().

Смежные вопросы