Согласованно понимать программно-аппаратное взаимодействие с DMA и шинами.

Я получил некоторый уровень знаний по нескольким компонентам (включая программное и аппаратное обеспечение), которые участвуют в общих транзакциях DMA на платах на основе ARM, но я не понимаю, как все это идеально интегрировано, я не нашел полной последовательности описание об этом.

Я запишу высокий уровень знаний, которые у меня уже есть, и я надеюсь, что кто-то может исправить меня, где я ошибаюсь, и заполнить недостающие части, чтобы вся картина была ясной. Мое описание начинается с программного обеспечения пользовательского пространства и углубляется до компонентов оборудования. Непонятые части выделены жирным курсивом.

  • Приложение пользовательского режима запрашивает чтение / запись с какого-либо устройства, т.е. выполняет операцию ввода-вывода.
  • Операционная система получает запрос и передает его соответствующему драйверу (каждая ОС имеет свой собственный механизм для этого, мне не нужно здесь углубляться в подробности, но если вы хотите поделиться своими соображениями, пожалуйста)
  • Драйвер, отвечающий за обработку запроса ввода-вывода, должен знать адрес, на который сопоставлено устройство (так как я заинтересован в платах на основе ARM, на самом деле существует только отображенный в память ввод-вывод и нет порта I/O). В большинстве случаев (если мы рассматриваем платы, подобные смартфонам) существует ядро ​​linux, которое анализирует адреса устройств из дерева устройств, которое дается из загрузчика во время загрузки (современный подход), или linux предварительно скомпилирован для конкретного семейства моделей и платы с адресами устройств внутри нее (жестко закодировано в исходном коде) (в старом и устаревшем подходе). В некоторых случаях (что часто случается в смартфонах) часть драйверов предварительно компилируется и просто упаковывается в ядро, т.е. их источник закрыт, поэтому адреса, соответствующие устройствам, неизвестны. Это правильно?
  • Учитывая, что драйвер знает адрес соответствующих регистров устройства, с которым он хочет установить связь, он выделяет буфер (обычно в пространстве ядра), в который устройство будет записывать свои данные (с помощью DMA). Драйвер должен информировать устройство о местонахождении этого буфера, но адреса, с которыми работают устройства (для управления памятью), отличаются от адресов, с которыми работают драйверы (ЦП), следовательно, драйвер должен информировать устройство о "шинном адресе" буфера, который он только что выделил. Как водитель сообщает устройству об этом адресе? Насколько популярно использование IOMMU? при использовании IOMMU есть один аппаратный компонент, который управляет адресацией или один на устройство?
  • Затем драйвер дает команду устройству выполнить свою работу (манипулируя его регистрами), и устройство передает выходные данные непосредственно в выделенный буфер в памяти. Здесь я немного запутался с отношением устройство-драйвер: шина: контроллер шины: фактическое устройство. Возьмем, к примеру, какое-то воображаемое устройство, которое умеет общаться в протоколе I2C; SoC определяет интерфейс шины I2C - что это на самом деле? шина I2C имеет какой-то контроллер шины? Процессор взаимодействует с интерфейсом шины I2C или напрямую с устройством? (т.е. интерфейс шины I2C является бесшовным). Я думаю, что кто-то с некоторым опытом работы с драйверами устройств мог бы ответить на этот вопрос легко..
  • Устройство заполняет канал DMA. Поскольку устройство не подключено напрямую к памяти, а подключено через некоторую шину к контроллеру DMA (который управляет шиной), оно взаимодействует с DMA для передачи необходимых данных в выделенный буфер в памяти. Когда поставщик плат использует IP-ядра ARM и спецификации шины, этот шаг включает в себя транзакции по шине из спецификации AMBA (то есть AHB/multi-AHB/AXI) и некоторый протокол между устройством и DMAC поверх него. Я хотел бы узнать больше об этом шаге, что на самом деле происходит? Есть много спецификаций для контроллера DMA от ARM, какая из них популярна? что устарело?
  • Когда устройство выполнено, оно отправляет прерывание, которое передается в ОС через контроллер прерываний, и обработчик прерываний ОС направляет его соответствующему драйверу, который теперь знает, что передача DMA завершена.

1 ответ

Здесь вы слегка перепутали две вещи - есть некоторые устройства (например, UART, контроллеры MMC, аудиоконтроллеры, как правило, устройства с низкой пропускной способностью), которые полагаются на внешний контроллер DMA ("механизм DMA" в терминологии Linux), но многие устройства просто самостоятельно управляйте шиной и выполняйте свои собственные DMA напрямую (например, графические процессоры, хост-контроллеры USB и, конечно, сами контроллеры DMA). Первый включает в себя кучу дополнительных сложностей с программированием ЦП контроллера DMA, так что я собираюсь проигнорировать это и просто рассмотреть прямую прямую шину DMA.

В типичном SoC ARM кластеры ЦП и другие главные периферийные устройства, а также контроллер памяти и другие подчиненные периферийные устройства соединены вместе с различными межсоединениями AMBA, образуя единую "шину" (как правило, все сопоставляются с "платформой шины" в Linux), по которой ведущие обращаются к ведомым в соответствии с адресными картами межсоединения. Вы можете с уверенностью предположить, что драйверы устройств знают (по дереву устройств или жестко закодировано), где устройства отображаются в карте физических адресов ЦП, поскольку в противном случае они были бы бесполезны.

В более простых системах существует одна карта адресов, поэтому физические адреса, используемые ЦП для адресации ОЗУ и периферийных устройств, могут свободно использоваться другими мастерами как адреса DMA. Другие системы более сложные - одна из наиболее известных - BCM2835 от Raspberry Pi, в которой ЦП и ГП имеют разные адресные карты; например, межсоединение имеет аппаратную проводку, так что, когда графический процессор видит периферийные устройства по "адресу шины" 0x7e000000, ЦП видит их по "физическому адресу" 0x20000000. Кроме того, в системах LPAE с 40-битными физическими адресами для межсоединения может потребоваться предоставить разные виды для разных мастеров - например, в SoC TI Keystone 2 все DRAM находятся выше 32-битной границы с точки зрения CPU, поэтому 32-разрядные мастера DMA были бы бесполезны, если бы соединение не показывало им другую карту адресов. Для Linux, проверьте dma-ranges свойство дерева устройства для того, как описываются такие трансляции CPU→bus. ЦП должен учитывать эти переводы, когда указывает мастеру доступ к определенному ОЗУ или периферийному адресу; Драйверы Linux должны использовать API сопоставления DMA, который обеспечивает соответственно преобразованные адреса DMA.

IOMMU обеспечивают большую гибкость, чем фиксированные смещения межсоединений - как правило, адреса могут быть переназначены динамически, и для мастеров целостности системы может быть предотвращен доступ к любым адресам, кроме адресов, сопоставленных для DMA в любой момент времени. Кроме того, в системе LPAE или AArch64 с более чем 4 ГБ ОЗУ IOMMU становится необходимым, если 32-разрядное периферийное устройство должно иметь доступ к буферам в любом месте ОЗУ. Вы увидите IOMMU на многих современных 64-битных системах с целью интеграции устаревших 32-битных устройств, но они также становятся все более популярными для виртуализации устройств.

Топология IOMMU зависит от системы и используемых IOMMU - система, с которой я сейчас работаю, имеет 7 отдельных устройств ARM MMU-401/400 перед отдельными периферийными устройствами шины; ARM MMU-500, с другой стороны, может быть реализован как единое общесистемное устройство с отдельным TLB для каждого ведущего устройства; у других поставщиков есть свои собственные проекты. В любом случае, с точки зрения Linux, большинство драйверов устройств должны использовать вышеупомянутый API сопоставления DMA для выделения и подготовки физических буферов для DMA, что также автоматически настроит соответствующие сопоставления IOMMU, если устройство подключено к нему. Таким образом, отдельные драйверы устройств не должны заботиться о наличии IOMMU или нет. Однако другие драйверы (обычно драйверы графического процессора) зависят от IOMMU и требуют полного контроля, поэтому управляйте сопоставлениями напрямую через API IOMMU. По сути, таблицы страниц IOMMU настроены для отображения определенных диапазонов физических адресов* на диапазоны виртуальных адресов ввода / вывода, эти IOVA присваиваются устройству как адреса DMA (т. Е. Шины), а IOMMU переводит IOVA обратно в физические адреса как устройство обращается к ним. После завершения операции DMA драйвер обычно удаляет сопоставление IOMMU, чтобы освободить пространство IOVA и чтобы устройство больше не имело доступа к ОЗУ.

Обратите внимание, что в некоторых случаях передача DMA является циклической и никогда не заканчивается. С чем-то вроде контроллера дисплея, CPU может просто отобразить буфер для DMA, передать этот адрес контроллеру и запустить его, а затем он будет непрерывно выполнять чтение DMA, чтобы отсканировать все, что CPU записывает в этот буфер, пока он не будет сказал остановить.

Другие периферийные шины за пределами соединения SoC, такие как I2 C / SPI / USB / и т. Д. работать, как вы подозреваете, - есть контроллер шины (который сам по себе является устройством на шине AMBA, поэтому к нему может применяться любое из вышеперечисленного) с собственным драйвером устройства. В грубом обобщении, ЦП не связывается напрямую с устройствами на внешней шине - где драйвер для устройства AMBA говорит "записать X в регистр Y", что просто происходит, когда ЦП выполняет сохранение по адресу, отображенному в памяти.; где драйвер устройства I2 C говорит "записать X в регистр Y", ОС обычно имеет некоторый уровень абстракции шины, который реализует драйвер контроллера шины, в результате чего ЦПУ программирует контроллер с помощью команды "запись X для регистрации Y на устройстве Z". "аппаратное обеспечение контроллера шины отключится и сделает это, а затем уведомит ОС об ответе периферийного устройства через прерывание или каким-либо другим способом.

* технически сам IOMMU, будучи более или менее "просто другим устройством", может иметь другую карту адресов в соединении, как описано выше, но я сомневаюсь в здравомыслии любого, кто на самом деле строит такую ​​систему.

Другие вопросы по тегам