Фантазии о Вселенной и мой личный сайт
2.5 Аппаратные прерывания

2.5 Аппаратные прерывания

В режиме реальных адресов принято отображать аппаратные прерывания на фиксированные вектора: IRQ 0..7 - на вектора прерываний 8..0Fh, IRQ 8..15 - на 70h..7Fh. При работе в защищённом режиме такая схема работы IRQ нам не подходит, т.к. вектора 8..0Fh заняты исключениями. В связи с этим возникает необходимость при установке системы прерываний в защищённом режиме перенаправить аппаратные прерывания на другие вектора, лежащие за пределами 00..1Fh, а при возврате в режим реальных адресов - обратно, на 8..0F и 70h..7Fh.

Обработкой аппаратных прерываних в процессорах Intel386 и Intel486 занимается микросхема 8259A, а в Pentium и старше - продвинутый программируемый контроллер прерываний APIC (Advanced Programmable Interrupt Controller). Программирование APIC-а - это отдельная тема, а так как в этом разделе мы рассматриваем установку системы прерываний в защищённом режиме, то программировать APIC не будем. APIC обладает замечательным свойством - его можно отключить или, другими словами, запретить (disable) и тогда он будет эмулировать работу внешнего контроллера прерываний 8259A. Этим мы и воспользуемся.

APIC есть только в процессорах, начиная с Pentium, да и то не у всех, поэтому возникает необходимость обнаружения APIC в процессоре. В начале нашего примера будет сделан вызов на процедуру "what_cpu", которая выполнит следующее:

  • Не допустит выполнение программы, если процессор не 32-разрядный (i286 или XT).
  • Произведёт поиск локального APIC в процессоре и если обнаружит его, то установит переменную db APIC_presence в 1, иначе - в 0.

Текст этой процедуры здесь не приводится, т.к. обнаружение APIC затрагивает другие темы, которые здесь не обсуждаются - определение типа процессора и команда CPUID; по этой же причине, комментарии в самой процедуре минимальны. Исходный текст "what_cpu" заложен внутри исходника примера, который будет приведен в конце следующей главы.

Программирование контроллера прерываний также является отдельной темой, поэтому комментарии и здесь минимальны. Пока просто используйте эти "магические" действия:

  1. Процедура P_Mode_redirect_IRQ отключает APIC, по мере необходимости и перенаправляет прерывания IRQ на вектора 20h..2Fh. Далее во всех наших примерах будет использоваться такая схема распределения векторов прерываний:
        00h..1Fh - исключения
        20h..2Fh - IRQ
        30h..FFh - программные прерывания
    
  2. Процедура R_Mode_redirect_IRQ используется перед возвратом в R-Mode, она восстанавливает вектора прерываний IRQ.
  3. Процедура redirect_IRQ используется обеими вышеприведенными процедурами, её прообраз взят из BIOS-а и слегка модифицирован для наших примеров.
  4. Процедура disable_APIC запрещает APIC для правильной работы нашего примера, enable_APIC разрешает APIC только если он был включён.

Процедуры смотреть здесь.