- •Введение
- •Подсистема ввода-вывода: общие принципы построения и работы
- •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
3.2. Объекты подсистемы ввода-вывода
При разработке операционной системы Windows широко использовались принципы объектно-ориентированной технологии программирования. Подсистема ввода-вывода не является исключением. Ее работа основана на взаимодействии следующих программных объектов:
объект файл (file object)
объект устройство (device object)
объект драйвер (driver object)
объект пакет запроса ввода-вывода (Input-output Request Packet, IRP)
объект блок стека запроса ввода вывода (IRP stack block)
Рассмотрим структуру и назначение этих объектов более внимательно.
Объект файл
Объект файл представлен экземпляром структуры FILE_OBJECT. Отметим некоторые поля этой структуры:
PDEVICE_OBJECT DeviceObject – указатель на объект-устройство, содержащее файл (или на устройство ввода-вывода, адресуемое через файловый интерфейс);
UNICODE_STRING FileName – имя файла;
LARGE_INTEGER CurrentByteOffset – смещение от начала файла (используется только для синхронных на пользовательском уровне операций ввода-вывода с настоящими файлами);
BOOLEAN ReadAccess, WriteAccess, DeleteAccess – флаги разрешенного доступа;
BOOLEAN SharedRead, SharedWrite, SharedDelete – флаги разрешенных видов совместного доступа.
В рамках рассматриваемой темы, наиболее интересно поле DeviceObject, указывающее на объект устройство, сопоставленное с данным файлом.
Объект устройство
Объект устройство представлен в системе экземпляром структуры DEVICE_OBJECT. Отметим некоторые поля этой структуры:
LONG ReferenceCount – счетчик ссылок на данный объект;
PDRIVER_OBJECT DriverObject – указатель на объект драйвер, управляющий данным устройством;
PDEVICE_OBJECT NextDevice – указатель на следующее устройство в списке устройств, управляемых одним и тем же драйвером;
PDEVICE_OBJECT AttachedDevice – указатель на присоединенное устройство, которое должно продолжить обработку запроса при использовании многоуровневой структуры драйверов (например, функциональный драйвер может ссылаться на виртуальное устройство, сопоставленное с драйвером-фильтром нижнего уровня);
PIRP CurrentIrp – указатель на текущий пакет запроса ввода-вывода, обрабатываемый драйвером;
PVOID DeviceExtention – указатель на внешнюю область памяти, выделенную драйвером и сопоставленную с объектом устройство для хранения специфичных для драйвера и устройства данных.
Таким образом, объект устройство связывает объект файл с драйвером, пакетом запроса ввода-вывода и следующим устройством в стеке обработки запроса при многоуровневой обработке запроса ввода-вывода несколькими драйверами.
Объект драйвер
Объект драйвер представлен в системе экземпляром структуры DRIVER_OBJECT. Отметим некоторые поля этой структуры:
PDEVICE_OBJECT DeviceObject – начало списка устройств, управляемых данным драйвером;
PVOID DriverStart – точка входа в программу драйвера, взятая из файла образа драйвера; указывает на процедуру, выполняющую начальную инициализацию драйвера, включая сохранение в структуре DRIVER_OBJECT точек входа в процедуры драйвера;
UNICODE_STRING DriverName – имя файла с образом драйвера;
PDRIVER_UNLOAD DriverUnload – точка входа в процедуру выгрузки драйвера, выполняющую освобождение всех ресурсов;
PDRIVER_DISPATCH MajorFunction[] – массив адресов вхождения в процедуры драйвера.
Прежде всего, объект драйвер хранит адреса процедур, предоставляемых операционной системе драйвером для организации интерфейса доступа к устройству. Точки входа в процедуры драйвера называются диспетчерскими процедурами. Они хранятся в массиве MajorFunction и определенные следующим образом:
typedef NTSTATUS (*PDRIVER_DISPATCH) (PDEVICE_OBJECT, PIRP);
Таким образом, диспетчерская процедура получает указатель на пакет запроса ввода-вывода, хранящий код операции и параметры, и на объект устройство, к которому адресован запрос. Указание устройства необходимо, поскольку один и тот же драйвер может управлять несколькими устройствами.
Для каждого числового значения индекса массива MajorFunction определено символическое имя, позволяющее проще идентифицировать процедуры драйвера. В частности, определены следующие символические имена:
#define IRP_MJ_CREATE 0 #define IRP_MJ_CLOSE 2 #define IRP_MJ_READ 3 #define IRP_MJ_WRITE 4 #define IRP_MJ_DEVICE_CONTROL 14 #define IRP_MJ_PNP 27