Предыдущий раздел ПЕРЕКЛЮЧЕНИЕ ПРОЦЕССОРА  

24.3. Обработка прерываний

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

Допустим, что на ЦП выполняется прикладная программа, вошедшая в бесконечный цикл, вследствие ошибки программирования. Тогда для прекращения выполнения этой программы достаточно нажать ту комбинацию клавиш, которая специально предназначена для этой цели в используемой ВС. Например, в UNIX это одновременное нажатие клавиш <Ctrl>&<C>, <Ctrl>&<\>, или <Ctrl>&<Z>.  Следствием этого является выдача интерфейсным устройством клавиатуры аппаратного сигнала прерывания, который поступает в ЦП по ОШ. Процессор прерывает выполнение зациклившейся программы и начинает выполнять обработчик прерываний клавиатуры. Эта подпрограмма распознает код нажатой комбинации клавиш, например <Ctrl>&<C>, и обеспечивает завершение программы. (Обработчик прерываний клавиатуры прекращает выполнение текущей программы не сам, а использует для этого сигнал SIGINT, см. п. 3.4.2).

Прерывания от клавиатуры являются примером внешних аппаратных прерываний. Другим примером таких прерываний являются прерывания от таймера (см. п.5.5). Сигналы внешних аппаратных прерываний выдаются в ЦП различными ПУ (а точнее – их ИУ), которым требуется внимание со стороны программ ЦП. Эти сигналы передаются в ЦП по шине управления, которая входит в состав ОШ. Характерной особенностью внешних аппаратных прерываний является то, что их первичной причиной являются процессы, асинхронные (независимые) по отношению к текущей работе ЦП. Примером такого асинхронного процесса является деятельность пользователя по нажатию клавиш, приводящая к возникновению прерываний от клавиатуры и от мыши. Аппаратные процессы, протекающие в ПУ, также могут являться первичными источниками внешних аппаратных прерываний.

Характерной особенностью сигналов внешних аппаратных прерываний является то, что они должны обрабатываться в реальном времени, то есть интервал времени между моментом появления сигнала прерывания и завершением его обработки не должен превышать предельно допустимой величины, которая зависит от типа сигнала прерывания. Например, для таймера этот интервал не должен превышать один тик. Задержка завершения обработки на большую величину приведет к потере тика и, следовательно, к нарушению правильности системного времени.

Внешние аппаратные прерывания разделяются на маскируемые и немаскируемые прерывания. Немаскируемые прерывания – наиболее важные прерывания, обработка которых не может быть отложена ни на какое время. Сюда относятся прерывания, возникающие при сбоях питания. Соответствующие сигналы прерываний выдаются в ЦП аппаратными схемами контроля питания. Маскируемые прерывания – прерывания, обработка которых может быть отложена на время, требуемое ЦП для выполнения какой-то другой, более важной операции. Запрет всех маскируемых прерываний выполняет машинная команда cli, а разрешение – команда sti. Первая из этих команд сбрасывает, а вторая устанавливает флажок разрешения прерываний IF в регистре EFLAGS.

Кроме внешних аппаратных прерываний существуют также внутренние аппаратные прерывания, называемые обычно исключениями. Источником аппаратного сигнала исключения является одна из аппаратных схем самого ЦП. Он выдается в том случае, если при выполнении на ЦП очередной машинной команды возникла ситуация, требующая помощи со стороны системных программ. Например, если при выполнении на ЦП команды div (деление), получилось частное, величина которого превышает предельно допустимую емкость рабочего регистра, то возникает исключение «деление на нуль». Обработчик данного исключения посылает сигналSIGFPE, стандартная обработка которого приводит к завершению процесса.

В качестве второго примера рассмотрим исключение «трассировка». Данное исключение будет происходить при выполнении на ЦП каждой машинной команды, если установлен флаг TF в регистре EFLAGS. В результате этого наша прикладная программа будет «спотыкаться» - по завершению каждой команды программы будет инициироваться обработчик исключения, выполняющий посылку сигналаSIGTRAP. Обработчик данного сигнала выполняется в контексте текущего процесса и поэтому может вывести на экран информацию о состоянии этого контекста. В частности на экран может быть выведено содержимое регистров, образующих аппаратный контекст процесса.

Третий тип прерываний – программные прерывания (термин неудачный, но общепринятый). Причиной такого прерывания является сама программа (отсюда и название), а именно - попадание  на ЦП машинной команды int. Подобно исключениям программные прерывания являются синхронными к текущей работе ЦП, так как обслуживают выполняемую на нем программу. Но в отличие от исключений, моменты возникновения которых автору прикладной программы заранее не известны, команды int помещаются программистом в текст программы сознательно с целью выполнения системных вызовов. Заметим, что в однопрограммной ВС, например, на основе MS-DOS, не существует иного способа вызова из прикладной программы системных управляющих подпрограмм (ОС или BIOS), кроме применения команды программного прерывания int.

Все типы прерываний в системе пронумерованы. Номер прерывания выполняет роль не только системного, но и программного имени сигнала прерывания, используемого в качестве параметра команды int. Это позволяет вызывать подпрограмму обработчика прерываний не по ее начальному адресу (как в команде call), а по номеру, что намного удобнее. Кроме того, замена того или иного обработчика прерываний не требует внесения изменений в тексты прикладных программ, так как номер прерывания остается прежним. Естественно, что при передаче сигналов аппаратных прерываний передача номера прерывания требует намного меньше линий, чем потребовалось бы для передачи адреса. Примеры номеров прерываний:

    0       -        деление на нуль

    1       -        трассировка

    2       -        немаскируемое прерывание

Для того, чтобы ЦП мог выполнить преобразование номера прерывания в начальный адрес соответствующего обработчика прерываний, используется вектор прерываний – небольшая область данных, содержащая этот адрес. Все векторы прерываний сведены в единую таблицу векторов прерываний. При поступлении сигнала прерывания в ЦП, его аппаратура определяет по номеру прерывания расположение соответствующего вектора прерываний, считывает из него стартовый адрес обработчика прерываний и загружает его в регистры CS и EIP, выполняя тем самым инициирование обработчика прерываний. Перед этим прежние содержимые CS и EIP запоминаются в стеке. Там же запоминается и содержимое на момент прерывания регистра EFLAGS. В конце программы обработчика прерываний обычно находится команда iret, выполняющая загрузку в регистрыCS,EIP и EFLAGS значений, запомненных в стеке. В результате выполнения этой команды следующей командой, выполняемой на ЦП, будет очередная команда прерванной программы. Изложенная общая схема обработки прерываний справедлива и для реального, и для защищенного режимов работы ЦП. Но в каждом из этих режимов имеются важные особенности.

В реальном режиме, который “достался в наследство” от процессора i8086, объем адресного пространства ОП составляет всего 1 Мбайт, а все регистры ЦП 16-битные. Длина вектора прерываний составляет 4 байта. Первые два байта содержат смещение, а вторые – сегмент стартового адреса обработчика прерываний. Таблица векторов прерываний занимает первые 1024 байта ОП и их никогда нельзя использовать для других целей. Следовательно, общее число векторов прерываний 256. Таково максимальное число типов прерываний, которые могут существовать в системе.

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

Обработка прерываний в защищенном режиме ЦП имеет существенные отличия от реального режима. Перечислим основные из этих отличий.

1. Значительно расширен состав исключений. Некоторые из новых исключений:

0Ah – недействительный сегмент состояния задачи TSS;

0Bh – исключение отказ сегмента (см. п.6.2.2);

0Dh – исключение общее нарушение защиты (см. п.6.2.3);

0Eh – исключение отказ страницы (см. п.6.3.2).

Следствием появления новых исключений является то, что одни и те же номера прерываний в реальном и защищенном режимах процессора обозначают разные типы прерываний.

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

3. В защищенном режиме используется другая таблица векторов прерываний – IDT (дескрипторная таблица прерываний). Элементами IDT, то есть векторами прерываний, являются 8-байтовые системные дескрипторы - вентили прерываний и вентили задач. Структура вентиля приведена на рис.45. В младших двух битах байта доступа вентиля исключения содержится двоичное число 11, а для других типов прерываний – число 10. Напомним, что в вентиле задачи это число равно 01.

Наличие вIDT и вентилей прерываний и вентилей задач приводит к тому, что в отличие от реального режима обработчиками прерываний могут быть не только подпрограммы (они инициируются через вентили прерываний), но и процессы (инициируются через вентили задач). Естественно, что все обработчики прерываний, выполняемые в защищенном режиме, должны принадлежать ядру.

4. В отличие от реального режима таблица векторов прерываний IDT может располагаться в любом месте пространства ОП, распределяемом ядру. На ее положение в памяти указывает 6-байтовый регистр IDTR, имеющий структуру, аналогичную регистру GDTR (см. п. 6.2.1). Для загрузки этого регистра используется машинная команда lidt.  

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

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

Например, пусть текущая машинная команда выполняет какую-то операцию с ячейкой ОП. Если логическая страница программы, содержащая требуемую переменную, отсутствует в ОП, то выполнение данной команды завершится исключением 0Eh (отказ страницы). Обработчик данного исключения обеспечит подкачку требуемой страницы из области свопинга на диске в ОП. После этого логично повторить выполнение той команды, которая привела к исключению.

 


Предыдущий раздел В начало