Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Последняя лекция.doc
Скачиваний:
7
Добавлен:
09.09.2019
Размер:
88.06 Кб
Скачать

5.6 Обработка ввода-вывода одноуровневым и многоуровневым драйверами

Рассмотрим структуру пакета ввода-вывода IRP (I/O Request Packet). IRP состоит из фиксированного заголовка и одного или нескольких блоков стека IRP.

Заголовок содержит тип и размер запроса, указатель на буфер в случае буферизованного ввода-вывода, данные о текущем состоянии обработки IRP, изменяющиеся по мере обслуживания IRP, сведения о синхронности или асинхронности запроса.

Блок стека IRP содержит номер функции диспетчеризации драйвера, которую нужно вызвать для обработки запроса, параметры, специфичные для функции, и указатель на объект «файл» для вызывающего потока. Отметим, что у каждого процессора в системе имеется своя очередь IRP. Различают малые IRP с одним блоком стека и большие IRP с восьмью блоками стека.

Рассмотрим пример запроса на ввод-вывод, демонстрирующий взаимосвязи между IRP и объектами «файл», «устройство» и «драйвер» на примере одноуровневого драйвера.

Приложение

Системные сервисы

Диспетчер ввода-вывода

Заголовок IRP

Блок стека для WRITE

Объект «файл»

Объект «устройство»

Объект «драйвер»

Процедуры диспетчеризации

Инициация ввода-вывода

ISR

DPC-процедура

Драйвер устройства

Приложение отправляет файл на принтер, передавая дескриптор объекта «файл.», затем диспетчер ввода-вывода создает IRP с одним блоком стека, помещая туда параметры, необходимые для записи. Объект «файл» ссылается на объект «устройство», который, в свою очередь, ссылается на объект «драйвер». Используя объект «драйвер», диспетчер ввода-вывода находит процедуру диспетчеризации WRITE и вызывает ее, передавая IRP.

Рассмотрим механизм обработки запроса на ввод-вывод для одноуровневого драйвера. Такая обработка включает 6 этапов:

1) Формируется запрос на ввод-вывод через DLL в пользовательском режиме.

2) Вызывается сервис диспетчера ввода-вывода (например, NtWriteFile)

3) Диспетчер ввода-вывода создает IRP, описывающий запрос, и посылает его драйверу, вызывая свою внутреннюю функцию IoCallDriver.

4) Драйвер передает данные из IRP на устройство и инициирует ввод-вывод.

5) Когда устройство завершает операцию с данными, оно генерирует прерывание. После этого осуществляется поиск ISR для этого устройства по таблице диспетчеризации прерываний. Напомним, что ISR обрабатывают прерывания в два этапа. На первом этапе ISR обрабатывается на уровне Device IRQL, оставаясь на этом уровне столько времени, сколько нужно для того, чтобы сохранить состояние устройства и запретить от него дальнейшие прерывания. На втором этапе ISR помещает DPC в очередь и, со своей точки зрения, завершив обслуживание прерывания, заканчивается. Впоследствии, при вызове DPC-процедуры, драйвер уже окончательно обслуживает прерывание.

6) Последняя стадия обработки запроса на ввод-вывод называется завершением ввода-вывода. Драйвер вызывает функцию IoCompletionRequest для уведомления диспетчера ввода-вывода об обработке IRP. Действия, выполняемые подсистемой на этом этапе, различны для разных операций ввода-вывода. Например, все сервисы должны записать результат выполненной операции в блок статуса ввода-вывода – структуру данных, предоставляемую вызывающим потоком. Некоторые сервисы, выполняющие буферизованный ввод-вывод, требуют возврата данных вызывающему потоку. В любом случае подсистема ввода-вывода должна обеспечивать копирование данных из системной области памяти в адресное пространство процесса, которому принадлежит вызывающий поток. При синхронном выполнении ввода-вывода это адресное пространство является текущим и доступно напрямую. Если же IRP обрабатывается асинхронно, то диспетчер ввода-вывода должен отложить завершение IRP до тех пор, пока у него не появится возможность обращаться к нужному адресному пространству. Чтобы получить доступ к этому адресному пространству, диспетчер ввода-вывода должен иметь средства запуска передачи данных именно в контексте вызывающего потока, т.е. процесс этого потока должен быть текущим и его адресное пространство должно быть активным для процессора. Эта проблема решается с использованием APC режима ядра. Напомним, что APC выполняется только в контексте определенного потока в отличие от DPC. Диспетчер ввода-вывода ставит APC в очередь для завершения обработки запроса на ввод-вывод в контексте вызывающего потока.

Когда вызывающий поток получит управление при низком IRQL процессора, APC процедура скопирует данные, если они есть, и код возврата в адресное пространство вызывающего потока, освобождает IRP и переводит дескриптор файла в свободное состояние. Только теперь ввод-вывод завершен и другие потоки, ждущие освобождения дескриптора этого файла, могут выполняться.

Для многоуровневых драйверов активно используется стек блоков IRP. Рассмотрим запрос записи на диск. Диспетчер ввода-вывода получает запрос на ввод-вывод, создает IRP, заполняет его первый блок стека и передает его драйверу файловой системы. Драйвер файловой системы заполняет второй блок стека IRP и вызывает драйвер диска. IRP можно считать аналогом стека в отношении добавления и удаления данных. После генерации устройством прерывания, процедура ISR дискового драйвера его обслуживает, ставя в очередь DPC-блок. DPC-процедура дискового драйвера выталкивает второй блок из стека блоков IRP и вызывает драйвер файловой системы. Драйвер файловой системы выполняет собственно освобождение IRP.