Ремонт, сервис, услуги » Информация » Объекты прерываний




Объекты прерываний

Автор: addministr от 5-06-2014, 21:46

Категория: Информация



Ядро предоставляет переносимый механизм — управляющий объект ядра, называемый объектом прерывания, который позволяет драйверам устройств регистрировать процедуры обработки прерываний (ISR) для своих устройств. Объект прерывания содержит всю информацию, необходимую ядру для того, чтобы связать ISR устройства с конкретным уровнем прерывания, включая адрес ISR, IRQL-уровень, на котором прерывается устройство, и запись в таблице диспетчеризации прерываний ядра (IDT), с которой нужно сопоставить ISR. При инициализации объекта прерывания в нем сохраняются несколько инструкций на языке ассемблера, так называемый код диспетчеризации, копируемый из шаблона обработки прерывания, KiInterruptTemplate.

Этот код выполняется при возникновении прерывания. Этот резидентный код объекта прерывания вызывает настоящий диспетчер прерывания, которым обычно является либо процедура KiInterruptDispatch, либо процедура KiChainedDispatch, передавая ему указатель на объект прерывания. KiInterruptDispatch является процедурой, используемой для векторов прерывания, для которых зарегистрирован только один объект прерывания. KiChainedDispatch является процедурой для векторов, совместно используемых несколькими объектами прерываний. Объект прерывания содержит информацию, которая нужна этой второй процедуре диспетчера для обнаружения и правильного вызова ISR-процедуры, предоставляемой драйвером устройства. Объект прерывания также хранит в себе IRQL, связанный с прерыванием, чтобы процедура KiInterruptDispatch или KiChainedDispatch перед вызовом ISR смогла поднять IRQL на правильный уровень, а затем, после возвращения управления из ISR, соответствующим образом понизить IRQL. Этот процесс, выполняемый в два этапа, нужен потому, что при начальной диспетчеризации способов передачи указателя (или какого-нибудь другого аргумента на этот случай) объекту прерывания не существует, поскольку начальная диспетчеризация осуществляется оборудованием. На мультипроцессорной системе ядро выделяет и инициализирует объект прерывания для каждого центрального процессора, позволяя локальному APIC этого процессора принимать конкретное прерывание.

На Windows-системах x64 ядро оптимизирует диспетчер прерываний, используя специальные процедуры, сохраняющие циклы процессора, пропуская ненужные функции, например, функцию KiInterruptDispatchNoLock, используемую для прерываний, не имеющих связанную с ними и управляемую ядром спин-блокировку (обычно используется драйверами, требующими синхронизации с их ISR-процедурами), и функцию KiInterruptDispatchNoEOI. Функция KiInterruptDispatchNoEOI используется для прерываний, запрограммировавших APIC в режим автоматического завершения прерывания — «Auto-End-of-Interrupt» (Auto-EOI), — поскольку контроллер прерываний пошлет сигнал EOI автоматически, ядру не нужно выполнять дополнительный код для самостоятельного осуществления EOI. И наконец, конкретно для прерывания профилирования производительности (performance/profiling) используется обработчик KiInterruptDispatchLBControl, поддерживающий регистр управления последним условным переходом Last Branch Control MSR, доступный на современных центральных процессорах. Этот регистр позволяет ядру отслеживать или сохранять инструкцию условного перехода при трассировке; при прерывании эта информация будет потеряна, поскольку она не сохраняется в контексте регистра обычного прерывания, поэтому для его сохранения должен быть добавлен специальный код.

Эта функция используется, к примеру, прерываниями производительности и профилирования HAL, в то время как другие процедуры прерываний HAL пользуются «неблокируемым» кодом диспетчеризации, поскольку HAL не требует от ядра синхронизации с его ISR. Еще один обработчик прерывания ядра KiFloatingDispatch используется для прерываний, требующих сохранения состояния в формате числа с плавающей точкой. В отличие от кода режима ядра, которому обычно не разрешается использовать операции с плавающей точкой (MMX, SSE, 3DNow!), поскольку относящиеся к ним регистры не будут сохраняться при переключениях контекста, ISR-процедуры могут нуждаться в использовании этих регистров (например, ISR видеокарты, выполняющей быструю операцию рисования). При подключении прерывания драйверы могут установить аргумент FloatingSave в TRUE, требуя от ядра использования процедуры диспетчеризации с числами с плавающей точкой, которая сохранит регистры, используемые для этих чисел (это существенно увеличивает время обработки прерывания). Следует заметить, что эта функция поддерживается только на 32-разрядных системах. На рисунке показана типовая схема управления прерываниями, связанными с объектами прерываний.

Объекты прерываний


Используя отладчик ядра, можно просмотреть детали объекта прерывания, включая его IRQL, адрес ISR и специализированный код диспетчеризации прерывания. Сначала нужно запустить команду !idt и обнаружить запись, включающую ссылку на I8042KeyboardInterruptService, ISR-процедуру для PS2-клавиатуры: 81: fffffa80045bae10 i8042prt!I8042KeyboardInterruptService (KINTERRUPT fffffa80045bad80) Для просмотра содержимого объекта прерывания, связанного с данным прерыванием, нужно запустить команду dt nt!_kinterrupt.
Адрес ISR-процедуры для объекта прерывания хранится в поле ServiceRoutine(которое команда !idt показывает в своем выводе), а код прерывания, выполняемый при его возникновении, хранится в массиве DispatchCodeв конце объекта прерывания. Хранящийся там код прерывания запрограммирован на создание фрейма системного прерывания в стеке и на последующий вызов функции, чей адрес хранится в поле DispatchAddress(KiInterruptDispatchв данном примере), с передачей этой функции указателя на объект прерывания.



Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

Архив | Связь с админом | Конфиденциальность

RSS канал новостей     Яндекс.Метрика