Введение в обработку прерываний
Одной из основных обязанностей NT является сопряжение компьютера с его периферийными устройствами. Подобно почти всем современным операционным системам, NT может динамически объединять программы драйверов устройств для управления устройствами. Драйверы устройств обычно используют сигналы прерываний для связи с контролируемыми ими устройствами. Когда устройство завершает указанную драйвером операцию, или когда устройство имеет новые данные для драйвера, устройство генерирует сигнал прерывания. В зависимости от состояния CPU, либо функция драйвера немедленно обслуживает прерывание, либо CPU помещает прерывание в очередь для обслуживания позднее.
Объекты – прерывания
Драйверам устройств необходим способ сообщения 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.
Рис. 14. Ход обслуживания прерывания NT
NT также имеет механизм обработки прерываний, не зарегистрированных драйверами устройств. В процессе инициализации системы NT программирует контроллер прерываний так, чтобы указывать на функции ISR по умолчанию. Функции ISR по умолчанию осуществляют специальную обработку, когда система генерирует ожидаемые прерывания. Например, ISR ошибки отсутствия страницы должна выполнить обработку в ситуации, при которой программа ссылается на виртуальную память, которая не имеет выделенного пространства в физической памяти компьютера.
Такая ситуация может возникнуть когда программы взаимодействуют с файловой системой для получения данных из файла подкачки или исполняемого файла, или когда программы ссылаются на недействительный адрес. NT программирует незарегистрированные прерывания так, чтобы они указывали на обработчики ISR, которые распознают, что система сгенерировала неразрешенное прерывание. Почти все эти ISR высвечивают синий экран смерти (BSOD – blue screen of death) для уведомления системного администратора о том, что произошло неразрешенное прерывание.