PersCom — Компьютерная Энциклопедия Компьютерная Энциклопедия

Введение

Взаимодействие через пространство памяти

В реальном режиме (при отключенной страничной переадресации) физический адрес, фигурирующий на системной шине, совпадает с линейным адресом, формируемым прикладной программой. Тут все просто, правда, в стандартном (а не большом) реальном режиме доступен только первый мегабайт адресного пространства (то есть из устройств доступны только отображенные на область UMA).

В защищенном режиме, в принципе, доступно все физическое адресное пространство, но появляются проблемы, связанные с отображением линейных адресов на физические. Страничной переадресацией (поддержкой таблиц) ведает ОС, и у разных программных компонентов (приложений, драйверов, динамических модулей) имеются различающиеся возможности взаимодействия с системой управления памятью. Напомним, что у каждой задачи может быть своя карта адресов, в которой не обязательно будут присутствовать физические адреса всех устройств.

Для обращения к регистрам устройства, расположенным в пространстве памяти (или к области памяти устройства), программа должна узнать физический адрес данной области. Далее она должна запросить у ОС линейный адрес, на который отображается этот физический адрес, и обращаться к нему по этому линейному адресу. Иного пути добраться до физического устройства у программы нет, и если ОС откажет в данном запросе, устройство окажется для этой программы недоступным. Для обращения к устройствам через пространство памяти у процессоров x86 предусмотрено большое число разнообразных инструкций, выполняющих как просто пересылку, так и работающих с операндами в памяти (то есть в устройстве). Инструкции, модифицирующие ячейки памяти, порождают на системной шине блокированные транзакции «чтение-модификация-запись». Этот тип транзакций не приветствуется с точки зрения эффективности использования времени шины, так что предпочтительно избегать таких инструкций при взаимодействии с устройствами. Заметим, что инструкции процессора обычно не порождают эффективных пакетных транзакций на шине PCI, они вызывают лишь одиночные транзакции1. Некоторые программные ухищрения, позволяющие повысить эффективность программно-управляемого обмена, будут описаны дальше.

При организации прямого доступа к памяти, как по стандартным каналам DMA, так и при использовании ведущих устройств шин ISA и PCI, возникает ряд проблем, связанных со страничным преобразованием адресов. Программе требуется организовать обмен данными между устройством и некоторым буфером данных в ОЗУ, с которым программа общается по линейным адресам, а устройство — по физическим. Отметим ряд существенных моментов:

  • программа должна запросить у ОС физический адрес, которому соответствует линейный адрес предполагаемого буфера обмена. Именно этот физический адрес должен задаваться устройству, осуществляющему DMA (или централизованному контроллеру DMA), при инициализации сеанса обмена (при указании начального адреса, длины блока и запуске канала);
  • физические страницы, к которым обращаются по DMA, должны быть зафиксированы: механизм замещения страниц не должен их затрагивать, по крайней мере, пока не завершится обмен по DMA;
  • если буфер данных не умещается в одной логической странице, возникает проблема пересечения границ. Обычный контроллер DMA работает по последовательно изменяемым (инкрементируемым или декрементируемым) адресам. При пересечении границы логической страницы, возможно, потребуется скачок физического адреса, поскольку следующая логическая страница может иметь физическое отображение в произвольном (относительно предыдущей страницы) месте ОЗУ. Чаще всего ОС оперирует страницами по 4 Кбайт, при этом пересылка больших блоков данных ведется «короткими перебежками», между которыми должна выполняться повторная инициализация контроллера DMA.

Проблема пересечения границ решается усложнением контроллеров DMA — применением «разбросанной записи» в память (scatter write) и «собирающего чтения» памяти (gather read). В этом случае контроллеру DMA задается список описателей блоков (начальный адрес и длина), каждый из которых не пересекает границ логической страницы. Отработав очередной блок памяти, контроллер переходит к следующему, и так до конца списка. Такие возможности имеет, например, стандартный контроллер PCI IDE. Для передачи логически непрерывного буфера данных описатели его блоков могут быть сокращены. Так, например, можно задать полный физический адрес начала буфера, его длину и только список базовых адресов занимаемых им страниц. На каждой странице, кроме начальной, данные будут начинаться с нулевого адреса; на каждой странице, кроме последней, данные будут доходить до последнего адреса. Вместо длины буфера можно задавать и физический адрес его конца. Такие варианты описаний используются, например, в хост-контроллерах шин USB и FireWire.

Проблема пересечения границ может решаться и иначе, без усложнения контроллера DMA. Для этого в памяти резервируется буфер значительного размера, отображенный на непрерывную область физической памяти, и обмен данными физическое устройство выполняет только с этим буфером. Однако рядовое приложение не может создать такой буфер, он может быть организован лишь драйвером устройства. Приложения могут лишь получать указатели на этот буфер и обмениваться с ним данными. Таким образом, по пути от приложения к устройству появляется дополнительная «перевалочная база» (буфер драйвера) и, соответственно, дополнительная пересылка данных, что приводит к дополнительным затратам времени.