- •Лекция №7-8. Подсистема в/в. Пакеты запросов ввода/вывода (irp). [7.1] Подсистема в/в и её характеристики.
- •[7.2] Структура irp
- •[7.2.1] Поля в Фиксированной части irp.
- •[7.2.2.] Поля в Стеке размещения Ввода - вывода irp.
- •[7.3] Описание Буфера Данных
- •[7.4] Коды Функции Ввода - вывода
- •[8.1] Передача данных посредством irp и диспетчерские точки входа драйвера
- •[8.1.1] Запросы чтения и записи irp_mj_read и irp_mj_write [8.1.1.1] Определение метода передачи буфера для запросов чтения-записи
- •[8.1.1.2] Получение буфера
- •[8.1.1.3] Завершение запроса в/в
- •[8.1.1.4] Пример обработки запросов чтения/записи
- •[8.1.2.1] Пояснения по использованию
- •[8.1.2.2] Задание кода управления вводом/выводом (ioctl)
- •[8.1.2.3] Получение буфера
- •[8.1.2.4] Завершение запроса в/в
- •[8.1.2.5] Пример обработки
Лекция №7-8. Подсистема в/в. Пакеты запросов ввода/вывода (irp). [7.1] Подсистема в/в и её характеристики.
На предыдущей лекции мы рассмотрели схему использования системных сервисов, т.е. прохождение запроса в/в от приложения к драйверу и обратно. Компонентом ОС, отвечающим за реализацию этой схемы, является Диспетчер ввода/вывода. Диспетчер в/в является компонентом более общей модели – подсистемы в/в.
Подсистема в/в включает в себя все компоненты, которые обеспечивают возможность осуществления в/в. В число этих компонент входит Диспетчер в/в и все драйвера режима ядра.
В числе характеристик подсистемы в/в NT принято выделять следующие:
Согласованность и высокая структурированность
Переносимость между процессорными архитектурами
Конфигурируемость
Вытесняемость и прерываемость
Поддержка многопроцессорности
Объектная базированность (но не объектная ориентированность)
Асинхронность
Подсистема в/в управляется пакетами
Подсистема в/в многоуровневая (послойная модель)
Как уже говорилось, подсистема в/в NT управляется пакетами. При таком подходе каждый запрос в/в описывается своим собственным пакетом запроса в/в (I/O Request Packet - IRP).
При задействовании системного сервиса (например, при запросе на чтение или запись в файл), Диспетчер в/в обрабатывает этот запрос путем создания пакета IRP, описывающего запрос, и затем передает указатель на этот пакет драйверу для обработки.
[7.2] Структура irp
IRP содержит всю необходимую информацию для полного описания запроса Ввода – вывода Диспетчеру Ввода - вывода и драйверам устройств. IRP описывается стандартной структурой типа "IRP", показанной на рис. 1.
Структура IRP специально разработана для поддержки многоуровневой модели в/в, при которой запрос в/в последовательно обрабатывается стеком из нескольких драйверов.
Для обеспечения этого каждый Пакет Запроса Ввода - вывода состоит из двух частей: "фиксированной" части и Стека Ввода - вывода. Фиксированная часть IRP содержит информацию относительно той части запроса, которая или не изменяется от драйвера к драйверу, или которую не надо сохранять при передаче IRP от одного драйвера к другому. Стек Ввода - вывода содержит набор Стеков Размещения Ввода - вывода, каждый из которых содержит информацию, специфическую для каждого драйвера, который может обрабатывать запрос.
Рис. 1
Примечание.
Пакеты IRP всегда выделяются из невыгружаемой системной памяти (nonpaged pool), поэтому к ним может осуществляться обращение из функций, работающих на любом уровне IRQL.
Как уже говорилось, драйвера подразделяются на 3 класса по их положению в стеке драйверов: драйвера высшего уровня, драйвера промежуточного уровня и драйвера низшего уровня.
Драйвер высшего уровня – это верхний драйвер в стеке драйверов, получающий запросы через Диспетчер в/в от компонентов прикладного уровня.
Драйвер высшего уровня (или, что более правильно, устройство высшего уровня) имеет один или несколько стеков размещения в/в.
Число стеков размещения в/в устанавливается Диспетчером в/в в поле StackSize объекта-устройство. По умолчанию это значение равно 1. Присваивание происходит при создании устройства функцией IoCreateDevice(). Если вы создаёте многоуровневый драйвер, вы должны установить StackSize на 1 больше, чем StackSize объекта-устройство, над которым вы будете размещать свое устройство. В случае, если ваше устройство будет использовать больше одного устройства уровнем ниже, поле StackSize вашего устройства должно быть на 1 больше максимального значения StackSize из всех устройств уровнем ниже.