Объекты - прерывания
Драйверам устройств необходим способ сообщения NT, что
они хотят, чтобы исполнялась определенная функция, когда процессор получает
прерывание, относящееся к их устройствам. Для этого драйверы устройств
с помощью Диспетчера ввода/ вывода регистрируют функцию обработки прерывания
(Interrupt Service Routine, ISR) посредством вызова функции loConnectlnterrupt.
Параметры, передаваемые в loConnectlnterrupt описывают все свойства ISR
драйвера, включая ее адрес, прерывание, к которому подключена ISR и то,
могут ли другие устройства совместно использовать это же прерывание.
Функция loConnectlnterrupt инициализирует объект-прерывание (Interrupt
Object), для того чтобы хранить информацию о прерывании и подключенной
ISR. loConnectlnterrupt программирует также аппаратуру прерываний для
того, чтобы указывать код, который loConnectlnterrupt поместила в объект-прерывание.
Таким образом, когда CPU получит прерывание, управление немедленно перейдет
к коду в объек-те-прерывание. Этот код вызовет вспомогательную функцию
обслуживания прерывания, KilnterruptDispatch, которая повысит уровень
IRQL процессора, вызовет соответствующую ISR, и понизит IRQL до предыдущего
значения. KilnterruptDispatch также получает спин-блокировку, индивидуальную
для прерывания, и удерживает ее, пока выполняется ISR (см. раздел «Механизмы
синхронизации»). Спин-блокировка гарантирует, что ISR не будет одновременно
исполняться более чем на одном процессоре, а это может привести к печальным
последствиям.
В NT, ISR обычно не делает ничего, кроме чтения минимального количества
информации из прерывающего устройства и подтверждения устройству того
факта, что драйвер «увидел» прерывание. В других операционных системах
ISR часто выполняют дополнительные обязанности, такие, как полная обработка
прерывания путем чтения больших буферов данных, или записи больших буферов
данных в устройство. Однако, одна из задач NT - минимизировать время,
проводимое на повышенных уровнях IRQL, поэтому NT откладывает большую
часть обслуживания прерывания до момента уменьшения уровня IRQL. Процедуры
ISR запрашивают отложенный вызов процедур (Deferred
Procedure Call, DPC) для информирования Диспетчера ВВОДА/ВЫВОДА
о том, что у них имеется работа для исполнения на нижнем уровне IRQL.
DPC - еще одна функция в драйвере, которую вызовет Диспетчер ввода/вывода
после завершения ISR; DPC осуществляет почти все взаимодействие с устройством.
Рис. 14 описывает типичный ход обслуживания прерывания NT. Контроллер
устройства генерирует сигнал прерывания на шине процессора, который обрабатывает
контроллер прерываний процессора. Этот сигнал служит причиной для CPU
для выполнения кода в объекте-прерывании, зарегистрированном для прерывания.
Этот код, в свою очередь, вызывает вспомогательную функцию Kilnterrupt
Dispatch. KilnterruptDispatch вызывает ISR драйвера, которая запрашивает
DPC.
NT также имеет механизм обработки прерываний, не зарегистрированных драйверами
устройств. В процессе инициализации системы NT программирует контроллер
прерываний так, чтобы указывать на функции ISR по умолчанию. Функции ISR
по умолчанию осуществляют специальную обработку, когда система генерирует
ожидаемые прерывания. Например, ISR ошибки отсутствия страницы должна
выполнить обработку в ситуации, при которой программа ссылается на виртуальную
память, которая не имеет выделенного пространства в физической памяти
компьютера. Такая ситуация может возникнуть когда программы взаимодействуют
с файловой системой для получения данных из файла подкачки или исполняемого
файла, или когда программы ссылаются на недействительный адрес. NT программирует
незарегистрированные прерывания так, чтобы они указывали на обработчики
ISR, которые распознают, что система сгенерировала неразрешенное прерывание.
Почти все эти ISR высвечивают синий экран смерти (BSOD - blue screen of
death) для уведомления системного администратора о том, что произошло
неразрешенное прерывание.
Рис. 14
|