- •Глава 10. Подсистема управления вводом-выводом
- •10.1 Взаимодействие драйверов с программной и аппаратной средой
- •10.1.1 Конфигурация системы
- •10.1.2 Системные функции и взаимодействие с драйверами
- •1. Просматривается таблица файлов для того, чтобы убедиться в том, что ни
- •2. Если устройство символьного типа, ядро запускает процедуру закрытия уст-
- •Ibm 370 имеется инструкция "Start I/o" (Начать ввод-вывод), которая иниции-
- •10.1.2.4 Стратегический интерфейс
- •10.1.2.5 Ioctl
- •Ioctl(fd,command,arg);
- •10.1.2.6 Другие функции, имеющие отношение к файловой системе
- •10.1.3 Программы обработки прерываний
- •5, Как пользуясь блочным интерфейсом, так и не прибегая к структурированию
- •0, Младший - 21. Файл "/dev/rdsk15" соответствует устройству посимвольного
- •10.3 Терминальные драйверы
- •Ioctl. Когда соответствующие критерии удовлетворены, программа обработки
- •Ioctl для того, чтобы перевести терминал в режим без обработки: он отключает
- •10.3.5 Назначение операторского терминала
- •10.3.6 Драйвер косвенного терминала
- •10.3.7 Вход в систему
- •10.4 Потоки
- •10.4.2 Анализ потоков
10.4.2 Анализ потоков
Ричи упоминает о том, что им была предпринята попытка создания потоков
только с процедурами "вывода" или только с процедурами обслуживания. Однако,
процедура обслуживания необходима для управления потоками данных, так как
модули должны иногда ставить данные в очередь, если соседние модули на время
закрыты для приема данных. Процедура "вывода" так же необходима, поскольку
данные должны иногда доставляться в соседние модули незамедлительно. Напри-
мер, строковому интерфейсу терминала нужно вести эхо-сопровождение ввода
данных на терминале в темпе с процессом. Системная функция write могла бы
запускать процедуру "вывода" для следующей очереди непосредственно, та, в
свою очередь, вызывала бы процедуру "вывода" для следующей очереди и так да-
лее, не нуждаясь в механизме диспетчеризации. Процесс приостановился бы в
случае переполнения очередей для вывода. Однако, со стороны ввода модули не
могут приостанавливаться, поскольку их выполнение вызывается программой об-
работки прерываний, иначе был бы приостановлен совершенно безобидный про-
цесс. Связь между модулями не должна быть симметричной в направлениях ввода
и вывода, хотя это и делает схему менее изящной.
Также было бы желательно реализовать каждый модуль в виде отдельного
процесса, но использование большого количества модулей привело бы к перепол-
нению таблицы процессов. Модули наделяются специальным механизмом диспетче-
ризации - программным прерыванием, независимым от обычного планировщика про-
цессов. По этой причине модули не могут приостанавливать свое выполнение,
так как они приостанавливали бы тем самым произвольный процесс (тот, который
прерван). Модули должны хранить внутри себя информацию о своем состоянии,
что делает лежащие в их основе программы более громоздкими, чем если бы при-
остановка выполнения была разрешена.
В реализации потоков можно выделить несколько отклонений или несоответс-
твий:
* Учет ресурсов процесса в потоках затрудняется, поскольку модулям необя-
зательно выполняться в контексте процесса, использующего поток. Ошибочно
предполагать, что все процессы одинаково используют модули потоков, пос-
кольку одним процессам может потребоваться использование сложных сетевых
протоколов, тогда как другие могут использовать простые строковые интер-
фейсы.
* Пользователи имеют возможность переводить терминальный драйвер в режим
без обработки, в котором функция read возвращает управление через корот-
кий промежуток времени в случае отсутствия данных (например, если
326
newtty.c_cc[VMIN] = 0 на Рисунке 10.17). Эту особенность сложно реализо-
вать в потоковой среде без подключения специальной программы на уровне
заголовка потока.
* Потоки выступают средствами линейной связи и не могут позволить произво-
дить с легкостью мультиплексирование на уровне ядра. В примере использо-
вания окон, рассмотренном в предыдущем разделе, выполнялось мультиплек-
сирование на уровне пользовательского процесса.
Несмотря на эти несоответствия, с потоками связываются большие надежды в
совершенствовании разработки модулей драйвера.
.te1 10.5 ВЫВОДЫ
Данная глава представляет собой обзор драйверов устройств в системе
UNIX. Устройства могут быть либо блочного, либо символьного типа; интерфейс
между устройствами и остальной частью ядра определяется типом устройств. Ин-
терфейсом для устройств блочного типа выступает таблица ключей устройств
ввода-вывода блоками, состоящая из точек входа, соответствующих процедурам
открытия и закрытия устройств и стратегической процедуре. Стратегическая
процедура управляет передачей данных от и к устройству блочного типа. Интер-
фейсом для устройств символьного типа выступает таблица ключей устройств по-
символьного ввода-вывода, которая состоит из точек входа, соответствующих
процедурам открытия и закрытия устройства, чтения, записи и процедуре ioctl.
Системная функция ioctl использует при обращении к устройствам символьного
типа свой собственный интерфейс, который позволяет осуществлять передачу уп-
равляющей информации между процессами и устройствами. По получении прерыва-
ния от устройства ядро вызывает программу обработки соответствующего преры-
вания, опираясь на информацию, хранящуюся в таблице векторов прерываний, и
на параметры, сообщенные устройством, от которого поступило прерывание.
Дисковые драйверы превращают номера логических блоков, используемые фай-
ловой системой, в физические адреса на диске. Блочный интерфейс дает возмож-
ность ядру буферизовать данные. Взаимодействие без обработки ускоряет
ввод-вывод на диск, но игнорирует буферный кеш, увеличивая тем самым шансы
разрушить файловую систему.
Терминальные драйверы осуществляют непосредственное взаимодействие с
пользователями. Ядро связывает с каждым терминалом три символьных списка,
один для неструктурированного ввода с клавиатуры, один для ввода с обработ-
кой символов стирания, удаления и возврата каретки и один для вывода. Сис-
темная функция ioctl дает процессам возможность следить за тем, как ядро об-
рабатывает вводимые данные, переводя терминал в канонический режим или уста-
навливая значения различных параметров для режима без обработки символов.
Getty-процесс открывает терминальные линии и ждет связи: он формирует группу
процессов во главе с регистрационным shell'ом, инициализирует с помощью фун-
кции ioctl параметры терминала и обращается к пользователю с предложением
зарегистрироваться. Установленный таким образом операторский терминал посы-
лает процессам в группе сигналы в ответ на возникновение таких событий, как
"зависание" пользователя или нажатие им клавиши прерывания.
Потоки выступают средством повышения модульности построения драйверов
устройств и протоколов. Поток - это полнодуплексная связь между процессами и
драйверами устройств, которая может включать в себя строковые интерфейсы и
протоколы для промежуточной обработки данных. Модули потоков характеризуются
четко определенным взаимодействием и гибкостью, позволяющей использовать их
в сочетании с другими модулями. Эта гибкость имеет особое значение для сете-
вых протоколов и драйверов.