Прямой доступ к памяти (DMA)

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

Терминальные устройства

Ранние терминалы были телетайпными машинами (отсюда и произошло имя tty для драйвера последовательного порта). Консольное устройство было разработано в середине прошлого века с целью отправки и приема текста по телеграфным сетям. В ранних 60-х телетайп превратился в ранний стандарт RS-232 и стал использоваться во множестве появляющихся микрокомпьютеров. В терминалах 70-х телетайп использовался для связи компьютеров. Настоящие терминалы стали редкостью. Популярные на мейнфреймах и мини-компьютерах в 70-х, терминалы были заменены на компьютерах 80-х программными эмуляторами терминалов.

Замечание о сетевых устройствах

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

Обзор символьных устройств

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

Операции с устройством

Базовое обобщенное блочное устройство имеет open, close (освобождение), ioctl и, что самое главное, функцию request. По крайней мере функции open и close могут быть простыми счетчиками. Интерфейс ioctl() может использоваться для отладки и выполнения измерений при прохождении через различные слои программного обеспечения. Функция request, вызываемая, когда запрос помещается в очередь файловой системой, извлекает структуру запроса и обрабатывает его содержимое. В зависимости от того, является ли запрос запросом на чтение или на запись, устройство выполняет соответствующее действие.

Пример: «обобщенное» блочное устройство

Рассмотрим слой обобщенного блочного устройства. В соответствии с рис. 5.4 он находится выше слоя физического устройства и сразу под слоем файловой системы. Основная задача слоя обобщенного устройства - это поддержание очереди запросов и связанные с ней операции.
Сначала мы регистрируем наше устройство с помощью register_blkdev (maj or, dev_name, fops). Эта функция получает старший номер запроса, имя блочного устройства (появляющееся в директории /dev) и указатель на структуру файловой операции. В случае удачи возвращается желаемый старший номер.
Далее мы создаем структуру gendisk.

Очередь запросов

В Linux 2.6 каждое блочное устройство имеет собственную очередь запросов, обрабатывающую запросы ввода-вывода к устройству. Процесс может обновлять очередь запросов устройства только в том случае, если заблокирует очередь запросов. Давайте рассмотрим структуру request_crueue.include/1inux/blkdev.h
270 struct reguest_queue
271 {

272 /*
273 * Объединение с головой очереди для разделения кеша
274 */
275 struct list_head queue_head;
276 struct request *last_merge;
277 elevator_t elevator; 278

279 /*
280 * очередь запрашивает свободный список для записи и для чтения
281 */

Предварительный планировщик ввода-вывода

Главной проблемой предварительного планировщика ввода-вывода является интенсивное поступление операций записи. Так как он нацелен на максимизацию эффективности чтения, запрос на запись может предваряться чтением, из-за чего головка диска перейдет на новую позицию, а затем для выполнения операции записи будет возвращаться назад, в начальную позицию. Предварительный планировщик ввода-вывода пытается предупредить следующую операцию и таким образом повысить производительность ввода-вывода.

Предельный планировщик ввода-вывода

Безоперационный планировщик страдает одним недостатком: при достаточно близких запросах новый запрос никогда не будет обработан. Многие новые запросы, близкие к существующим, будут слиты или вставлены между существующими элементами, а новый запрос будет отброшен и помещен в конец очереди ожидания. Предельный планировщик пытается решить эту проблему с помощью назначения каждому запросу предельного времени и, кроме того, использует две дополнительные очереди для эффективной обработки времени, а в остальном он похож по эффективности на безоперационный алгоритм для работы с диском.

Безоперационный планировщик ввода-вывода

Безоперационный планировщик ввода-вывода получает запросы и сканирует очередь, определяя, можно ли объединить их с уже существующими запросами. Это возможно, если новый запрос близок к существующему. Если новый запрос необходим для блока перед тем, для которого уже есть запрос, он добавляется в начало существующего запроса. Если новый запрос существует для блока после того, для которого уже есть запрос, он добавляется в конец существующего запроса. При нормальном вводе-выводе мы читаем файл с начала до конца, и поэтому большинство запросов сливаются с уже существующими запросами.

RSS-материал