Обработчик прерываний¶
Обработчик прерываний — это специальная подпрограмма (функция) операционной системы или встроенного программного обеспечения, предназначенная для обслуживания запросов, поступающих от аппаратных устройств или программного обеспечения в виде прерываний. Обработчик прерываний является ключевым элементом механизма прерываний, который позволяет процессору временно приостановить выполнение текущей программы, сохранить её состояние и переключиться на выполнение кода, необходимого для реакции на событие, вызвавшее прерывание. После завершения обработки прерывания процессор восстанавливает состояние прерванной программы и продолжает её выполнение с точки остановки.
¶История
Концепция прерываний возникла в ранних компьютерных системах 1950-х годов. Первоначально процессоры работали в режиме циклического опроса (polling), когда центральный процессор периодически проверял состояние каждого устройства ввода-вывода. Это приводило к неэффективному использованию вычислительных ресурсов, так как процессор тратил время на ожидание событий, которые могли не происходить.
В 1951 году в компьютере UNIVAC I была реализована система, позволяющая внешним устройствам сигнализировать процессору о необходимости обслуживания. Однако полноценный механизм прерываний с сохранением контекста и векторизацией появился в 1960-х годах, например, в мейнфреймах IBM System/360. В этих системах обработчики прерываний были организованы в виде таблицы векторов прерываний, где каждому типу прерывания соответствовал адрес его обработчика.
С развитием микропроцессоров (Intel 8080, 8086, Motorola 68000) механизм прерываний стал стандартным. В 1980-х годах операционные системы, такие как MS-DOS и Unix, начали активно использовать обработчики прерываний для управления драйверами устройств. В современных системах (Windows, Linux, macOS) обработчики прерываний интегрированы в ядро операционной системы и работают в контексте прерывания с минимальной задержкой.
¶Классификация обработчиков прерываний
Обработчики прерываний классифицируются по нескольким признакам.
¶По источнику прерывания
- Аппаратные обработчики — обслуживают прерывания от внешних устройств (клавиатура, мышь, жёсткий диск, сетевая карта, таймер). Они вызываются сигналами от контроллера прерываний (например, Intel 8259A PIC или APIC).
- Программные обработчики — обслуживают прерывания, инициированные программным обеспечением с помощью специальных инструкций процессора (например,
INTв архитектуре x86). Используются для системных вызовов и обработки исключений (деление на ноль, нарушение защиты памяти). - Исключения (traps) — обрабатывают ошибки, возникающие в процессе выполнения инструкций (страничные ошибки, недопустимые опкоды). Они синхронны по отношению к текущему потоку выполнения.
¶По приоритету и маскированию
- Маскируемые — могут быть временно заблокированы (замаскированы) путём установки флага прерывания в процессоре. Обычно это аппаратные прерывания от периферийных устройств.
- Немаскируемые (NMI) — не могут быть заблокированы программно. Используются для критических событий, таких как сбой питания, ошибка памяти или аппаратный сброс.
- Векторизованные — каждому прерыванию соответствует уникальный номер (вектор), который указывает на адрес обработчика в таблице векторов прерываний (IDT — Interrupt Descriptor Table). Это стандартный механизм в архитектурах x86, ARM, RISC-V.
- Невекторизованные — все прерывания одного типа обслуживаются одним обработчиком, который самостоятельно определяет источник события (например, в старых системах с одним контроллером прерываний).
¶По времени выполнения
- Верхняя половина (top half) — быстрый, атомарный код, выполняющий минимально необходимые действия (например, считывание данных из порта ввода-вывода или подтверждение приёма прерывания). Выполняется в контексте прерывания с запрещёнными другими прерываниями.
- Нижняя половина (bottom half) — отложенная обработка, выполняемая в менее критичном контексте (например, в виде отложенных процедур (DPC) в Windows или tasklet/workqueue в Linux). Позволяет минимизировать время блокировки прерываний.
¶Устройство и механизм работы
Обработчик прерываний представляет собой последовательность машинных инструкций, адрес которой хранится в таблице векторов прерываний (IDT). При возникновении прерывания процессор выполняет следующие шаги:
- Сохранение контекста — на стек помещаются регистры состояния (флаги, счётчик команд) и, в зависимости от архитектуры, дополнительные регистры.
- Определение вектора — процессор считывает номер прерывания из шины данных (для аппаратных) или из инструкции (для программных) и обращается к IDT по этому номеру.
- Переход к обработчику — процессор загружает в счётчик команд адрес, хранящийся в соответствующей записи IDT, и начинает выполнение кода обработчика.
- Выполнение обработчика — обработчик выполняет необходимые действия: чтение/запись в порты устройств, обновление структур данных ядра, отправка сигналов процессам.
- Восстановление контекста — после завершения обработчик выполняет инструкцию возврата из прерывания (например,
IRETв x86), которая восстанавливает сохранённые регистры и продолжает выполнение прерванной программы.
В многопроцессорных системах каждый процессор имеет собственную таблицу IDT, а контроллер прерываний (APIC) распределяет прерывания между ядрами для балансировки нагрузки.
¶Примеры обработчиков прерываний
¶Обработчик прерывания таймера (IRQ 0)
Один из наиболее часто срабатывающих обработчиков. В операционных системах общего назначения (Windows, Linux) он вызывается с частотой 100–1000 Гц. Обработчик выполняет следующие действия:
- Увеличивает счётчик системного времени (jiffies).
- Проверяет, не истекли ли таймеры процессов.
- Инициирует перепланировку задач (вызов планировщика).
- Обновляет статистику загрузки процессора.
¶Обработчик прерывания клавиатуры (IRQ 1)
При нажатии клавиши контроллер клавиатуры (8042) генерирует прерывание. Обработчик:
- Считывает скан-код из порта 0x60.
- Преобразует скан-код в символ или код клавиши.
- Помещает событие в буфер ввода (обычно кольцевой буфер).
- Пробуждает процесс, ожидающий ввода (например, терминал).
¶Обработчик страничной ошибки (исключение #PF)
Возникает при попытке доступа к виртуальной памяти, отсутствующей в физической памяти. Обработчик:
- Проверяет, является ли адрес допустимым (находится ли он в адресном пространстве процесса).
- Если допустим — загружает страницу с диска (подкачка) в физическую память.
- Если недопустим — завершает процесс с ошибкой сегментации (SIGSEGV).
¶Применение
Обработчики прерываний используются в следующих областях:
- Операционные системы — для управления драйверами устройств, планирования задач, обработки системных вызовов и исключений.
- Встраиваемые системы — в микроконтроллерах (ARM Cortex-M, AVR, STM32) обработчики прерываний используются для обслуживания таймеров, датчиков, интерфейсов связи (UART, SPI, I2C).
- Реального времени (RTOS) — в системах жёсткого реального времени обработчики прерываний должны иметь предсказуемое время выполнения для гарантии отклика.
- Виртуализация — гипервизоры (KVM, Xen) перехватывают прерывания от гостевых операционных систем и обрабатывают их через собственные обработчики.
¶Критика и ограничения
Обработчики прерываний имеют ряд ограничений:
- Время выполнения — обработчики должны выполняться максимально быстро, так как во время их работы другие прерывания могут быть заблокированы (особенно в однопроцессорных системах). Длительные обработчики могут привести к потере данных или пропуску событий.
- Сложность отладки — обработчики работают в контексте прерывания, где недоступны многие механизмы ядра (например, блокировки, планирование). Ошибки в обработчиках могут привести к зависанию системы или краху.
- Приоритетная инверсия — в многозадачных системах обработчик с низким приоритетом может блокировать высокоприоритетные задачи, если он удерживает ресурс.
- Безопасность — некорректно написанные обработчики могут быть использованы для атак (например, переполнение буфера в драйвере, обрабатывающем прерывания).
¶Интересные факты
- В архитектуре x86 количество векторов прерываний ограничено 256 (0–255). Из них первые 32 зарезервированы для исключений процессора (например, #DE — деление на ноль, #GP — общая защита).
- В Linux обработчики прерываний регистрируются с помощью функции
request_irq()и могут быть динамически назначены на любое ядро процессора через сродство прерываний (IRQ affinity). - В некоторых микроконтроллерах (например, ARM Cortex-M) обработчики прерываний могут быть написаны на языке высокого уровня (C/C++) без ассемблерных вставок, так как сохранение контекста выполняется аппаратно.
- В операционной системе Windows обработчики прерываний работают на уровне IRQL (Interrupt Request Level), где более высокий уровень блокирует прерывания с более низким уровнем.
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →


