Прерывания и особые ситуации: Защищенный режим

Печать
Программирование - Архитектура и система команд микропроцессоров x86

 

Работа механизма реакции на прерывания и особые ситуации в защищенном режиме базируется на специальной таблице дескрипторов прерываний (Protected-Mode Interrupt Descriptor Table – IDT). Базовый адрес (BASE) этой таблицы и ее предел (LIMIT) заносятся в регистр IDTR с помощью команды LIDT (см. рис. 3.3).

Таблица IDT содержит до 256 специальных дескрипторов, каждый из которых соответствует своему прерыванию. Эти дескрипторы занимают по 8 байт каждый и располагаются в таблице последовательно без каких-либо промежутков. Самый первый дескриптор, расположенный по самому младшему адресу в начале таблицы соответствует прерыванию 0, а самый последний дескриптор, расположенный по самому старшему адресу в таблице, соответствует прерыванию 255.

 

Таблица дескрипторов прерываний (IDT) в защищенном режиме работы

Рис. 3.3. Таблица дескрипторов прерываний (IDT) в защищенном режиме работы

 

В качестве дескрипторов таблицы IDT могут использоваться дескрипторы разного типашлюза прерывания, шлюза ловушки и шлюза задачи. Поведение процессора при поступлении запроса на прерывание зависит, как от типа применяемого для данного прерывания дескрипторов, так и от текущего уровня привилегий задачи.

В случае, если в качестве дескриптора прерывания используется шлюз задачи, процессор при поступлении запроса на прерывание выполняет все действия по переключению на новую задачу, сохраняя текущее состояние в TSS старой задачи и загружая новые значения в регистры из TSS задачи обработчика прерывания. Применение такого шлюза оправдано для обработки ошибок и сбоев, которые не могут быть обработаны в рамках текущей задачи (например, ошибки, возникающие при переключении задач).

Если в качестве дескриптора прерывания используется шлюз ловушки или шлюз прерывания, то переключения задач не происходит и программа обработчик функционирует в рамках той же задачи, что и прерванный код. Отличие шлюза прерывания состот лишь в том, что процессор автоматически сбрасывает флаг EFLAGS.IF при передаче управления в обработчик, чем обеспечивается маскирование внешних прерываний. В последующем, при возврате из процедуры обработчика прежнее значение регистра EFLAGS восстанавливается из стека.

 

Особенности работы процессора при передаче управления обработчику прерываний защищенного режима

Механизм защиты для прерываний в защищенном режиме функционирует практически таким же образом, как это происходит при выполнении команды вызова подпрограммы CALL. Некоторые особенности его работы заключаются в следующем:

  • процессор не проверяет текущий уровень привилегий CPL для внешних прерываний;
  • поскольку для прерываний не существует отдельного селектора, то все правила для запрашиваемого уровня привилегий селектора (RPL) игнорируются;
  • процессор проверяет уровень привилегий DPL шлюза только для программных прерываний, генерируемых командами INT n, INT 3, INTO, с тем, чтобы предотвратить генерацию таких прерываний, если CPL > DPL.

Если обработчик прерывания защищенного режима (Protected-mode Exception and Interrupt Handler) будет расположен в согласованном кодовом сегменте, то ему при получении управления будет доступен только сегмент стека и те сегменты, привилегии которых позволяют это. Если же обработчик будет размещен в несогласованном кодовом сегменте с нулевым уровнем привилегий, то независимо от CPL прерванной программы ему будут доступны все сегменты.

При поступлении запроса на прерывание процессор сохраняет текущие значения EFLAGS, CS и EIP в стеке. Если для обрабатываемого прерывания предусмотрена генерация кода ошибки, то этот код сохраняется в стеке сразу после значения EIP.

Когда передача управления в обработчик связана с изменением уровня привилегий на более высокий (меньшее числовое значение), это сопровождается переключением стека. Новые значения для SS и ESP берутся из TSS задачи в соответствии с уровнем привилегий обработчика. Переключение стека производится до сохранения указанных выше регистров, причем в новом стеке в первую очередь сохраняются значения SS и ESP, указывающие на старый стек (см. рис. 3.4.).

При передаче управления в обработчик через шлюз прерывания или шлюз ловушки процессор сбрасывает флаги EFLAGS.TF, EFLAGS.RF и EFLAGS.NT, чтобы отключить трассировку прерываний и некоторые особенности обработки вложенных задач. Кроме того, при использовании шлюза прерывания сбрасывается также и флаг разрешения прерываний EFLAGS.IF.

 

Стек после вызова прерывания или особой ситуации в защищенном режиме

Рис. 3.4. Стек после вызова прерывания или особой ситуации в защищенном режиме

 

Стек процессора Intel286 после вызова прерывания или особой ситуации заполняется аналогично, за исключением того, что сохраняемые значения 16-битные.

Процессоры Intel386 и Intel486 сохраняют код ошибки в стеке как 16-битное значение, а процессоры, начиная с Pentium – сохраняют его как 32-битное значение с нулевыми старшими битами.

 

Режим с поддержкой виртуальных флагов прерываний

В процессорах, начиная с Pentium, возможен специальный подвид защищенного режима с поддержкой виртуальных флагов прерываний (Protected-mode Virtual Interrupts), который включается установкой флага CR4.PVI. В этом режиме процессор обеспечивает автоматическую поддержку отслеживания запросов от внешних маскируемых источников прерываний для задач, выполняемых на уровне привилегий CPL = 3 при EFLAGS.IOPL < 3. Для обеспечения такой поддержки применяются специальные флаги VIF и VIP в регистре EFLAGS. Этот механизм во многом похож на режим EV86, который, в свою очередь, предназначен для работаты с виртуальными прерываниями в режиме V86.

В обычном защищенном режиме (CR4.PVI = 0), когда EFLAGS.IOPL < CPL, все попытки изменения флага EFLAGS.IF командами STI, CLI вызывают генерацию ошибки общей защиты (#GP). Когда же виртуальные прерывания инициализированы (CR4.PVI = 1) команды CLI и STI оказывают влияние на флаг EFLAGS.VIF, а флаг EFLAGS.IF при этом остается неизменным. При поступлении внешнего маскируемого прерывания процессор производит стандартное обращение к обработчику прерываний защищенного режима (процедура этого обращения описана выше). Обработчик прерывания должен произвести анализ флага EFLAGS.VIF и в зависимости от его значения произвести следующие действия:

  • если в момент поступления запроса на прерывание EFLAGS.VIF = 1, значит прерывания были разрешены в программе уровня привилегий 3 – обработчик защищенного режима может либо сам обработать это прерывание, либо передать управление в соответствующий обработчик в прерванной задаче, эмулируя поступление соответствующего внешнего прерывания;
  • если в момент поступления запроса на прерывание EFLAGS.VIF = 0, значит прерывания были запрещены в программе уровня привилегий 3, обработчик защищенного режима может сам обработать поступившее прерывание, но если это необходимо делать внутри программы уровня привилегий 3, обработчик защищенного режима устанавливает специальный флаг отложенного прерывания EFLAGS.VIP и возвращает управление в прерванную программу.

Если при выполнении программы уровня привилегий 3 процессор разрешает прием внешник маскируемых прерываний, уставливая флаг EFLAGS.VIF (например, командой STI), а флаг EFLAGS.VIP = 1, то перед установкой флага EFLAGS.VIF срабатывает вызов отложенного прерывания и генерируется ошибка общей защиты (#GP). Обработчик ошибки общей защиты должен распознавать такие ситуации и соответствующим образом обрабатывать поступившие запросы на прерывание. Рекомендуемая последовательность его действий перед возвратом управления в прерванную программу: очистка флага EFLAGS.VIP и установка флага EFLAGS.VIF в сохраненном в стеке образе регистра EFLAGS, возврат управления в прерванную программу.

В некоторых редких случаях флаги EFLAGS.VIP и EFLAGS.VIF могут оказаться установленными одновременно (например, командой IRETD или на уровне привилегий. отличном от 3). Тогда перед выполнением очередной команды программы уровня привилегий 3 генерируется ошибка общей защиты (#GP).

Таким образом, флаг EFLAGS.VIP никогда автоматически не изменяется процессором, а должен устанавливаться и сбрасываться программным обеспечением самостоятельно.

Текущие значения флагов EFLAGS.VIF и EFLAGS.VIP никак не влияют на работу процессора на уровне привилегий. отличном от 3.

Команды POPF/POPFD и PUSHF/PUSHFD выполняются при активированном механизме виртуальных прерываний защищенного режима (CR4.PVI = 1) точно также, как и без него (CR4.PVI = 0).