- •Введение
- •Подсистема ввода-вывода: общие принципы построения и работы
- •1.1. Взаимодействие процессора с внешними устройствами
- •1.2. Прямой доступ к памяти
- •Драйверы
- •Роль драйверов в операционной системе
- •Взаимодействие драйверов с компонентами операционной системы и пользовательскими программами
- •Стек обработки запросов ввода-вывода
- •Основы организации и работы подсистемы ввода-вывода unix
- •2.1. Драйверы в операционных системах семейства unix
- •Стратегическая функция драйвера блочного устройства
- •Функция обработки прерывания
- •Функция опроса устройства
- •Другие функции драйверов
- •Буферизация в символьных драйверах
- •Терминальный драйвер
- •2.2. Потоковая подсистема ввода-вывода в unix
- •Архитектура и принципы работы подсистемы streams
- •Архитектура и работа модулей потока
- •Функция модуля put
- •Функция модуля service
- •Структура сообщения
- •Основы организации и работы подсистемы ввода-вывода windows
- •3.1. Классификаций драйверов Windows
- •Драйверы пользовательского режима
- •Драйверы режима ядра
- •3.2. Объекты подсистемы ввода-вывода
- •Объект файл
- •Объект устройство
- •Объект драйвер
- •Объект пакет запроса ввода-вывода
- •Объект блок стека запросов ввода-вывода
- •3.3. Передача данных между пользовательским адресным пространством и пространством ядра
- •Буферизированный ввод-вывод
- •Прямой ввод-вывод
- •Ввод-вывод под управлением драйвера
- •3.4. Обработка запросов ввода-вывода
- •Прохождение запроса ввода-вывода вниз через стек обработки запросов ввода-вывода
- •Обработка прерывания по завершению ввода-вывода
- •Обратное прохождение запроса ввода-вывода вверх через стек запросов ввода-вывода
- •3.5. Буферизация запросов ввода-вывода
- •Системная очередь запросов
- •Очереди запросов под управлением драйвера
- •3.6. Диспетчер Plug-And-Play, установка и запуск драйверов
- •3.7. Диспетчер электропитания
- •3.8. Среда сетевых драйверов ndis
- •Драйверы среды ndis Минипорт-драйверы сетевых адаптеров
- •Драйверы протоколов
- •Промежуточные драйверы
- •Структура ndis пакета
- •Запросы к сетевым адаптерам
- •3.9. Порты завершения ввода-вывода
- •Заключение
- •Библиографический список
- •Оглавление
- •394026 Воронеж, Московский просп., 14
Архитектура и работа модулей потока
Архитектура модуля потока показана на рис. .10.
Рис.10. Архитектура модуля
Основными компонентами модуля являются очереди записи и чтения. Эти очереди имеют одинаковую структуру, поэтому рассмотрим только очередь записи.
Заголовок очереди представлен структурой queue, включающей следующие поля:
q_qinfo – указатель на структуру q_init, содержащей указатели на функции работы с очередью;
q_first и q_last – указатели соответственно на первое и последнее сообщение в списке сообщений очереди;
q_next – указатель на структуру очереди записи/чтения в следующем/предыдущем модуле.
Структура q_init в свою очередь содержит указатели на функции, обслуживающие очередь и на две структуры данных: структуру module_info – содержащей некоторые базовые параметры модуля, такие как размер сообщений, предельную длину очереди и т.п., и структуру module_stat – содержащей статистику работы модуля.
Для работы с очередью модуль должен предоставить 4 функции: open, close, put и service, указатели на которые и сохраняются в структуре q_init.
Функция open вызывается при открытии потока или встраивании модуля в поток. Функция close вызывается при закрытии потока или при удалении модуля из потока. Функции put и service рассмотрим более подробно.
Функция модуля put
Функция put осуществляет обработку сообщений, проходящих через модуль. Она вызывается модулем, когда он готов передать данные следующему модулю.
Алгоритм работы функции put показан на рис. .11.
Рис.11. Алгоритм работы функции put
Получив управление, функция put в первую очередь выполняет обработку полученного сообщения, определенную для данного модуля. Затем функция put передает сообщение следующему модулю в направлении передачи данных, для чего она вызывает функцию put следующего модуля и т.д., до тех пор, пока сообщение не достигнет драйвера при передаче вниз, или головного модуля при передаче вверх.
Если после обработки сообщения в каком-то модуле его функция put не может передать сообщение дальше, ввиду неготовности следующего модуля, функция put размещает обработанное сообщение в своей очереди записи или чтения, в зависимости от направления передачи и завершается.
Очереди модулей будут в дальнейшем обработаны асинхронно по инициативе операционной системы.
Рассмотрим теперь стандартную процедуру запроса готовности следующего модуля, упомянутую на блок-схеме на рис. .11. Проблема состоит в том, что модуль, непосредственно взаимодействующий с данным модулем, может не поддерживать буферизацию. Если сообщение будет передано такому модулю, а следующий за ним модуль окажется не готов принять сообщение, то сообщение будет потеряно.
Для преодоления описанной проблемы, проверка готовности модуля выполняется рекурсивно. Если проверяемый модуль не поддерживает буферизации, то он запрашивает готовность следующего модуля и т.д., пока не будет достигнут модуль с буферизацией. Если этот модуль готов принять сообщение, т.е. в его очереди достаточно свободного места, то подтверждение готовности передается по цепочке модулей обратно, вплоть до модуля, инициировавшего проверку.