Шрифт:
Рис. 9.30
ГЛАВА 10. ПОДСИСТЕМА УПРАВЛЕНИЯ ВВОДОМ-ВЫВОДОМ
Подсистема управления вводом-выводом позволяет процессам поддерживать связь с периферийными устройствами, такими как накопители на магнитных дисках и лентах, терминалы, принтеры и сети, с одной стороны, и с модулями ядра, которые управляют устройствами и именуются драйверами устройств, с другой. Между драйверами устройств и типами устройств обычно существует однозначное соответствие: в системе может быть один дисковый драйвер для управления всеми дисководами, один терминальный драйвер для управления всеми терминалами и один ленточный драйвер для управления всеми ленточными накопителями. Если в системе имеются однотипные устройства, полученные от разных изготовителей — например, две марки ленточных накопителей, — в этом случае можно трактовать однотипные устройства как устройства двух различных типов и иметь для них два отдельных драйвера, поскольку таким устройствам для выполнения одних и тех же операций могут потребоваться разные последовательности команд. Один драйвер управляет множеством физических устройств данного типа. Например, один терминальный драйвер может управлять всеми терминалами, подключенными к системе. Драйвер различает устройства, которыми управляет: выходные данные, предназначенные для одного терминала, не должны быть посланы на другой.
Система поддерживает "программные устройства", с каждым из которых не связано ни одно конкретное физическое устройство. Например, как устройство трактуется физическая память, чтобы позволить процессу обращаться к ней извне, пусть даже память не является периферийным устройством. Команда ps обращается к информационным структурам ядра в физической памяти, чтобы сообщить статистику процессов. Еще один пример: драйверы могут вести трассировку записей в удобном для отладки виде, а драйвер трассировки дает возможность пользователям читать эти записи. Наконец, профиль ядра, рассмотренный в главе 8, выполнен как драйвер: процесс записывает адреса программ ядра, обнаруженных в таблице идентификаторов ядра, и читает результаты профилирования.
В этой главе рассматривается взаимодействие между процессами и подсистемой управления вводом-выводом, а также между машиной и драйверами устройств. Исследуется общая структура и функционирование драйверов и в качестве примеров общего взаимодействия рассматриваются дисковые и терминальные драйверы. Завершает главу описание нового метода реализации драйверов потоковых устройств.
10.1 ВЗАИМОДЕЙСТВИЕ ДРАЙВЕРОВ С ПРОГРАММНОЙ И АППАРАТНОЙ СРЕДОЙ
В системе UNIX имеется два типа устройств — устройства ввода/вывода блоками и устройства неструктурированного или посимвольного ввода-вывода. Как уже говорилось в главе 2, устройства ввода-вывода блоками, такие как диски и ленты, для остальной части системы выглядят как запоминающие устройства с произвольной выборкой; к устройствам посимвольного ввода-вывода относятся все другие устройства, в том числе терминалы и сетевое оборудование. Устройства ввода-вывода блоками могут иметь интерфейс и с устройствами посимвольного ввода-вывода.
Пользователь взаимодействует с устройствами через посредничество файловой системы (см. Рисунок 2.1). Каждое устройство имеет имя, похожее на имя файла, и пользователь обращается к нему как к файлу. Специальный файл устройства имеет индекс и занимает место в иерархии каталогов файловой системы. Файл устройства отличается от других файлов типом файла, хранящимся в его индексе, либо "блочный", либо "символьный специальный", в зависимости от устройства, которое этот файл представляет. Если устройство имеет как блочный, так и символьный интерфейс, его представляют два файла: специальный файл устройства ввода-вывода блоками и специальный файл устройства посимвольного ввода-вывода. Системные функции для обычных файлов, такие как open, close, read и write, имеют то же значение и для устройств, в чем мы убедимся позже. Системная функция ioctl предоставляет процессам возможность управлять устройствами посимвольного ввода-вывода, но не применима в отношении к файлам обычного типа [29] . Тем не менее, драйверам устройств нет необходимости поддерживать полный набор системных функций. Например, вышеупомянутый драйвер трассировки дает процессам возможность читать записи, созданные другими драйверами, но не позволяет создавать их.
29
И наоборот, системная функция fcntl обеспечивает контроль над действиями, производимыми на уровне дескриптора файла, но не на уровне устройства. В других реализациях функция ioctl применима для файлов всех типов.
10.1.1 Конфигурация системы
Задание конфигурации системы это процедура указания администраторами значений параметров, с помощью которых производится настройка системы. Некоторые из параметров указывают размеры таблиц ядра, таких как таблица процессов, таблица индексов и таблица файлов, а также сколько буферов помещается в буферном пуле. С помощью других параметров указывается конфигурация устройств, то есть производятся конкретные указания ядру, какие устройства включаются в данную системную реализацию и их "адрес". Например, в конфигурации может быть указано, что терминальная плата вставлена в соответствующий разъем на аппаратной панели.
Существует три стадии, на которых может быть указана конфигурация устройств. Во-первых, администраторы могут кодировать информацию о конфигурации в файлах, которые транслируются и компонуются во время построения ядра. Информация о конфигурации обычно указывается в простом формате, и программа конфигурации преобразует ее в файл, готовый для трансляции. Во-вторых, администраторы могут указывать информацию о конфигурации после того, как система уже запущена; ядро динамически корректирует внутренние таблицы конфигурации. Наконец, самоидентифицирующиеся устройства дают ядру возможность узнать, какие из устройств включены. Ядро считывает аппаратные ключи для самонастройки. Подробности задания системной конфигурации выходят за пределы этой книги, однако во всех случаях результатом процедуры задания конфигурации является генерация или заполнение таблиц, составляющих основу программ ядра.