Всем привет, сегодня мы поговорим о DMA: именно о той технологии, которая помогает вашему компьютеру воспроизводить за вас музыку, выводить изображения на экран, записывать информацию на жесткий диск и при этом давать мизерную нагрузку на центральный процессор.
ДМА, что это? О чем ты говоришь?
DMA, или Direct Memory Access, — это технология прямого доступа к памяти, минуя центральный процессор.В эпоху 486-х и первых Пентиумов безраздельно господствовала шина ISA, а также метод обмена данными между устройствами — PIO (Programmed Input/Output).
PIO по своей сути прост: чтобы получить данные от устройства, драйвер операционной системы (или прошивка другого устройства) должен был прочитать эти данные из регистров устройства.
Давайте посмотрим на пример:
- На сетевую карту поступило 1500 байт данных.
- Сетевая карта инициирует прерывание, чтобы сообщить процессору, что данные необходимо извлечь из устройства, иначе произойдет так называемое переполнение буфера.
- Операционная система ловит прерывание от контроллера прерываний и отправляет его на обработку драйверу.
- Драйвер считывает данные из регистров сетевой карты в цикле, побайтно.
Но это всего лишь один Ethernet-пакет, представьте, сколько пакетов получает сетевая карта, когда вы читаете любимый хабрахабр.
Конечно, в реальности чтение в режиме PIO можно организовать и по 2,4 байта, но потеря производительности все равно будет катастрофической.
Когда объёмы данных, которыми оперирует процессор, стали увеличиваться, стало понятно, что необходимо минимизировать участие процессора в цепочке обмена данными, иначе всё будет сложно.
И тогда технология прямого доступа к памяти нашла активное применение.
Кстати, DMA используется не только для обмена данными между устройством и оперативной памятью, но и между устройствами в системе; Передача DMA возможна между двумя разделами оперативной памяти (правда, этот маневр неприменим к архитектуре x86).
Также в своем процессоре Cell компания IBM использует DMA в качестве основного механизма связи между элементами синергетической обработки (SPE) и центральным процессорным элементом (PPE).
Также каждый SPE и PPE могут обмениваться данными через DMA с оперативной памятью.
На самом деле этот метод является большим преимуществом Cell, поскольку он устраняет проблемы когерентности кэша во время многопроцессорной обработки данных.
И снова теория
Прежде чем мы перейдем к практике, хотелось бы выделить несколько важных аспектов программирования устройств PCI и PCI-E. Я кратко упомянул регистры устройств, но как процессор получает к ним доступ? Как многие из вас знают, в компьютерных технологиях есть такое понятие, как порты ввода-вывода (порты ввода/вывода).Они предназначены для обмена информацией между центральным процессором и периферийными устройствами, причем доступ к ним возможен с помощью специальных инструкций по сборке – вход/выход. BIOS (или OpenFirmware в системах на базе PPC) на ранних этапах инициализации устройств PCI, а также некоторых других (контроллер Super IO, контроллер устройств PS/2, таймер ACPI и т. д.) назначает собственный диапазон портов ввода-вывода для конкретный контроллер, где и отображаются регистры устройства.
Кроме того, регистры устройства могут быть сопоставлены с ОЗУ (регистры с отображением памяти), то есть с физическим адресным пространством.
Этот метод имеет ряд преимуществ, а именно:
- Скорость доступа к физической памяти выше, чем к портам ввода-вывода.
- Порты ввода-вывода могут отображать не более 65535 байт регистров, при этом размер оперативной памяти современных компьютеров во много раз больше.
- Чтение регистров устройства из ОЗУ проще, чем использование портов ввода-вывода :)
Итак, существует два метода переработки DMA: непрерывный DMA и рассеяние/сбор DMA.
Непрерывный прямой доступ к памяти
Этот метод очень прост и сейчас практически устарел, но до сих пор используется для программирования звуковых контроллеров (например, Envy24HT).Его принцип заключается в следующем:
- В оперативной памяти выделяется один буфер достаточно большого размера.
- Физический адрес (точнее адрес на шине раздела памяти, поскольку физический адрес и адрес шины равны в архитектуре x86, но не равны в PPC) этого буфера записывается в регистр устройства.
- Когда данные поступают на устройство, контроллер устройства инициирует передачу DMA.
- Когда буфер полностью заполнен, контроллер устройства выдает прерывание, сообщая ЦП, что буфер следует передать операционной системе.
- Драйвер операционной системы обрабатывает прерывание и передает полученные данные из буфера дальше по стеку устройств операционной системы.
Например, драйверы сетевых карт имели два таких буфера DMA: один для приема данных (rx), другой для отправки (tx).
Разброс/сбор DMA
С увеличением скорости Ethernet-адаптеров непрерывный DMA показал свою несогласованность.В основном из-за того, что требовались довольно большие области памяти, выделить которые порой было невозможно, поскольку в современных системах фрагментация физической памяти достаточно высока.
Во всем виноват механизм виртуальной памяти, без которого мы сегодня не можем жить :) Решение напрашивается само собой: использовать вместо одного большого раздела памяти несколько, но в разных регионах одной памяти.
Возникает вопрос, а как сообщить контроллеру устройства, как инициировать передачу DMA и по какому адресу записывать данные? И тогда нашли решение — использовать дескрипторы для описания каждой такой области в оперативной памяти.
Типичный дескриптор буфера DMA содержит следующие поля:
- Адрес раздела ОЗУ (а именно адрес шины), который предназначен для передачи DMA.
- Размер описываемого раздела оперативной памяти.
- Необязательные флаги и другие конкретные аргументы.
- Адрес следующего дескриптора в памяти.
Дескриптор, как и буфер DMA, находится в оперативной памяти.
Алгоритм рассеяния/сбора DMA следующий:
- Драйвер операционной системы выделяет и инициализирует дескрипторы буфера DMA.
- Драйвер выделяет буферы DMA (участки оперативной памяти для передачи DMA) и записывает необходимую информацию о них в дескрипторы.
- Устройство по мере необходимости заполняет буферы DMA, а после заполнения одного или нескольких буферов инициирует прерывание.
- Драйвер ОС просматривает все дескрипторы буфера DMA, определяет, какие из них были заполнены контроллером устройства, пересылает данные из буфера дальше по стеку устройства и помечает буфер как готовый к передаче DMA.
Контроллер может писать в первый свободный буфер DMA или просто писать подряд (дескрипторы буфера DMA в этом случае образуют односвязный кольцевой список) во все буферы и т. д.
Останавливаться.
Вот пожалуй и все на сегодня, иначе будет слишком много информации.
В следующей статье я покажу вам, как IOKit работает с уличной магией.
Жду ваших отзывов и дополнений ;)
Ссылки
[1] Спецификация локальной шины PCI Теги: #DMA #PIO #Системное программирование #драйвер #Системное программирование-
Сян Шу Чжи Сюэ
19 Oct, 24 -
Сервера Бесплатны До Конца Года
19 Oct, 24 -
Bgp Интер-Ас
19 Oct, 24 -
«Вести» Можно Найти На Мобильном Телефоне
19 Oct, 24 -
15 Лет В Isdef: Опыт Самой Старшей Участницы
19 Oct, 24