§ Аппаратные прерывания
В режиме реальных адресов принято отображать аппаратные прерывания на фиксированные вектора: 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.
Программирование контроллера прерываний также является отдельной темой, поэтому комментарии и здесь минимальны. Пока просто используйте эти "магические" действия:
- Процедура P_Mode_redirect_IRQ отключает APIC, по мере необходимости и перенаправляет прерывания IRQ на вектора 20h..2Fh. Далее во всех наших примерах будет использоваться такая схема распределения векторов прерываний:
00h..1Fh - исключения 20h..2Fh - IRQ 30h..FFh - программные прерывания
- Процедура R_Mode_redirect_IRQ используется перед возвратом в R-Mode, она восстанавливает вектора прерываний IRQ.
- Процедура redirect_IRQ используется обеими вышеприведенными процедурами, её прообраз взят из BIOS-а и слегка модифицирован для наших примеров.
- Процедура disable_APIC запрещает APIC для правильной работы нашего примера, enable_APIC разрешает APIC только если он был включён.
1; BX = { BL = Начало для IRQ 0..7, BH = начало для IRQ 8..15 } 2; DX = Маска прерываний IRQ ( DL - для IRQ 0..7, DH - IRQ 8..15 ) 3redirect_IRQ: 4 5 mov al, 11h 6 out 0xA0, al 7 out 0x20, al 8 9 ; Вектора Master / Slave 10 mov al, bh 11 out 0xA1, al 12 mov al, bl 13 out 0x21, al 14 15 mov al, 02 16 out 0xA1, al 17 mov al, 04 18 out 0x21, al 19 mov al, 01 20 out 0xA1, al 21 out 0x21, al 22 23 ; Маска прерываний 24 mov al, dh 25 out 0xA1, al 26 mov al, dl 27 out 0x21, al 28 29 ret