1.Внутреннее устройство Windows (гл. 1-4)
Шрифт:
Далее мы рассмотрим, как процессор уведомляется об аппаратных прерываниях, какие типы прерываний поддерживаются ядром и как драйверы устройств взаимодействуют с ядром (в процессе обработки прерываний). Кроме того, мы поговорим о распознавании ядром программных прерываний и об объектах, используемых для реализации таких прерываний.
Ha аппаратных платформах, поддерживаемых Windows, прерывания, связанные с внешним вводом-выводом, поступают по одной из линий контроллера прерываний. Контроллер в свою очередь связан с процессором единственной линией, по которой и уведомляет о прерывании. Как только процессор прерывается, он требует от контроллера запрос прерывания (interrupt request, IRQ). Контроллер транслирует IRQ в номер прерывания, используемый как индекс в структуре, называемой таблицей
ЭКСПЕРИМЕНТ: просмотр IDT
Просмотреть содержимое IDT, включая сведения об обработчиках ловушек, которые Windows назначила прерываниям, можно с помощью команды !idt отладчика ядра. Команда !idt без флагов показывает векторы, которые сопоставлены с адресами в модулях, отличных от Ntoskrnl.exe.
Ниже показано, что выводит команда !idt.
B системе, задействованной в этом эксперименте, номер прерывания 0x3C — с ISR драйвера клавиатуры (I8042prt.sys), а прерывание 0x3B совместно используется несколькими устройствами, в том числе видеоадаптером, шиной PCMCIA, портами USB и IEEE 1394, а также сетевым адаптером.
Windows увязывает аппаратные IRQ с номерами прерываний в IDT. Эта таблица используется системой и при конфигурировании обработчиков ловушек для исключений. Так, номер исключения для ошибки страницы на x86 и x64 (это исключение возникает, когда поток пытается получить доступ к отсутствующей или не определенной в виртуальной памяти странице) равен 0xe. Следовательно, запись 0xe в IDT указывает на системный обработчик ошибок страниц. Хотя архитектуры, поддерживаемые Windows, допус-каютдо 256 элементов в IDT, число IRQ на конкретной машине определяется архитектурой используемого в ней контроллера прерываний.
У каждого процессора имеется своя IDT, так что разные процессоры могут при необходимости выполнять разные ISR. Например, в многопроцессорной системе каждый процессор получает прерывания системного таймера, но обновление значения системного таймера в результате обработки этого прерывания осуществляется только одним процессором. Однако все процессоры используют это прерывание для измерения кванта времени, выделенного потоку, и для инициации новой процедуры планирования по истечении этого кванта. Аналогичным образом в некоторых конфигурациях может понадобиться, чтобы определенные аппаратные прерывания обрабатывал конкретный процессор.
B большинстве систем x86 применяется либо программируемый контроллер прерываний (Programmable Interrupt Controller, PIC) i8259A, либо его разновидность, усовершенствованный программируемый контроллер прерываний (Advanced Programmable Interrupt Controller, APIC) i82489. Новые компьютеры, как правило, оснащаются APIC Стандарт PIC был разработан для оригинальных IBM PC PIC работает только в однопроцессорных системах и имеет 15 линий прерываний. APIC и SAPIC (о нем чуть позже) способен работать в многопроцессорных системах и предлагает 256 линий прерываний. Intel совместно с другими компаниями создали спецификацию Multiprocessor (MP) Specification, стандарт для многопроцессорных систем x86, основанный на использовании APIC Для совместимости с однопроцессорными операционными системами и загрузочным кодом, запускающим многопроцессорную систему в однопроцессорном режиме, APIC поддерживает PIC-совместимый режим с 15 линиями прерываний и передачей прерываний лишь главному процессору. Архитектура APIC показана на рис. 3–2. Ha самом деле APIC состоит из нескольких компонентов: APIC ввода-вывода, принимающего прерывания от устройств, локальных APIC, принимающих прерывания от APIC ввода-вывода по выделенной шине и прерывающих pa-ботутого процессора, с которым они связаны, а также 18259А-совместимого контроллера прерываний, транслирующего входные сигналы APIC в соответствующие PIC-эквиваленты. APIC ввода-вывода отвечает за реализацию алгоритмов перенаправления прерываний, и операционная система выбирает нужный ей алгоритм (в Windows выбор возлагается на HAL). Эти алгоритмы равномерно распределяют между процессорами нагрузку, связанную с обработкой прерываний от устройств, и в максимальной мере используют все преимущества локальности, направляя такие прерывания процессору, который только что обрабатывал прерывания аналогичного типа.
Поскольку архитектура x64 совместима с операционными системами для x86, системы на базе x64 должны предоставлять те же контроллеры прерываний, что и на базе x86. Однако х64-версии Windows не будут работать на системах без APIC (т. е. они не поддерживают PIC).
B архитектуре IA64 используется контроллер прерываний Streamlined Advanced Programmable Interrupt Controller (SAPIC) — результат эволюционного развития APIC Главное различие между архитектурами APIC и SAPIC в том, что APIC ввода-вывода в APIC-системе направляет прерывания локальным APIC по выделенной шине APIC, тогда как в системе SAPIC прерывания передаются по шине ввода-вывода и системы (I/O and system bus) для большего быстродействия. Еще одно различие — перенаправление прерываний и балансировка нагрузки в APIC-системе обрабатывается самой шиной APIC, а в SAPIC-системе, где нет выделенной шины APIC, требуется, чтобы соответствующая поддержка была запрограммирована в микрокоде (прошивке). Ho, даже если эта поддержка имеется в микрокоде, Windows не использует ее — вместо этого она статически назначает прерывания процессорам по принципу карусели.
ЭКСПЕРИМЕНТ: просмотр конфигурации PIC и APIC
Конфигурацию PIC в однопроцессорной системе и APIC в многопроцессорной системе можно просмотреть с помощью команд !pic или !apic отладчика ядра. (Для этого эксперимента LiveKd не годится, так как она не может напрямую обращаться к оборудованию.) Ниже показан образец вывода команды !pic в однопроцессорной системе (учтите, что команда !pic не работает в системе, использующей APIC HAL).
Ha следующем листинге приводится выходная информация команды !apic в системе, использующей MPS HAL. Префикс «0:» в командной строке отладчика говорит о том, что текущие команды выполняются на процессоре 0, поэтому данный листинг относится к APIC ввода-вывода процессора 0.
Теперь взгляните на образец вывода команды !ioapic, показывающей конфигурацию APIC ввода-вывода:
Хотя контроллеры прерываний различают уровни приоритетов прерываний, Windows использует свою схему приоритетов прерываний, известную под названием уровни запросов прерываний (interrupt request levels, IRQL). Внутри ядра IRQL представляются в виде номеров 0-31 в системах x86 и 0-15 в системах x64 и IA64, причем больший номер соответствует прерыванию с более высоким приоритетом. Ядро определяет стандартный набор IRQL для программных прерываний, a HAL увязывает IRQL с номерами аппаратных прерываний. IRQL, определенные для архитектуры x86, показаны на рис. 3–3, а аналогичные сведения для архитектур x64 и IA64 — на рис. 3–4.
ПРИМЕЧАНИЕ Уровень SYNCH_LEVEL, используемый многопроцессорными версиями ядра для защиты доступа к индивидуальным для каждого процессора блокам PRCB (processor control blocks), не показан на этих схемах, так как его значение варьируется в разных версиях Windows. Описание SYNCH_LEVEL и его возможных значений см. в главе 6.
Рис. 3–4. Уровни запросов прерываний (IRQL) в системах x64 и IA64