Настройка отображения IRQ - PullRequest
9 голосов
/ 12 ноября 2008

Я следую нескольким учебникам и ссылкам, пытаясь настроить мое ядро. Я наткнулся на какой-то незнакомый код в учебнике, который его вообще не объясняет. Мне сказали, что это код, сопоставляющий 16 IRQs (0-15) с местами ISR 32-47:

void irq_remap(void)
{
    outportb(0x20, 0x11);
    outportb(0xA0, 0x11);
    outportb(0x21, 0x20);
    outportb(0xA1, 0x28);
    outportb(0x21, 0x04);
    outportb(0xA1, 0x02);
    outportb(0x21, 0x01);
    outportb(0xA1, 0x01);
    outportb(0x21, 0x0);
    outportb(0xA1, 0x0);
}

Код для outportb() выглядит следующим образом, но у меня уже есть четкое представление о том, что он делает:

void outPortB(unsigned short port, unsigned char data)
{
    __asm__ __volatile__ ("outb %1, %0" : : "dN" (port), "a" (data));
}

Следует отметить, что это на архитектуре x86 в защищенном режиме. Этот исходный код работает нормально, и я понимаю, что он делает, но я не понимаю, как он это делает. Может кто-нибудь объяснить мне, что здесь происходит, чтобы в случае, если мне нужно было расширить это, я буду знать, что я делаю?

Ответы [ 2 ]

12 голосов
/ 12 ноября 2008

outb и т.п., запись в аппаратные порты ввода-вывода. В основном, есть 2 основных варианта связи с устройством. Устройство может быть привязано к памяти или портам ввода-вывода.

Что касается того, как работает этот код, я прокомментирую его для вас:

ICW обозначает «Слова команд инициализации»

outportb(0x20, 0x11); /* write ICW1 to PICM, we are gonna write commands to PICM */
outportb(0xA0, 0x11); /* write ICW1 to PICS, we are gonna write commands to PICS */

outportb(0x21, 0x20); /* remap PICM to 0x20 (32 decimal) */
outportb(0xA1, 0x28); /* remap PICS to 0x28 (40 decimal) */

outportb(0x21, 0x04); /* IRQ2 -> connection to slave */ 
outportb(0xA1, 0x02);

outportb(0x21, 0x01); /* write ICW4 to PICM, we are gonna write commands to PICM */
outportb(0xA1, 0x01); /* write ICW4 to PICS, we are gonna write commands to PICS */

outportb(0x21, 0x0); /* enable all IRQs on PICM */
outportb(0xA1, 0x0); /* enable all IRQs on PICS */

надеюсь, это поможет

Добро пожаловать в мир разработчиков ОС :) Я также рекомендую посетить: http://forum.osdev.org/, это бесценный ресурс для нового разработчика хобби ОС.

1 голос
/ 31 августа 2010

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

Счастливый ответ заключается в том, что только первый PIC должен быть переназначен (переназначение второго предназначено только для удобства, поскольку оно начинается в int 70h). Вот цитата из оригинального AT BIOS.

INTA00    equ  020h        ; 8259 port
INTA01    equ  021h        ; 8259 port
INTB00    equ  0A0h        ; 2nd 8259
INTB01    equ  0A1h
INT_TYPE  equ  070h        ; start of 8259 interrupt table location

;---------------------------------------------------------
;    re-initialize the 8259 interrupt #1 controller chip :
;---------------------------------------------------------
  mov  al, 11h             ; icw1 - edge, master, icw4
  out  INTA00,al
  jmp  $+2                 ; wait state for i/o
  mov  al, 8               ; setup icw2 - int type 8 (8-f)
  out  INTA01, al
  jmp  $+2
  mov  al, 4               ; setup icw3 - master lv 2
  out  INTA01, al
  jmp  $+2
  mov  al, 1               ; setup icw4 - master, 8086 mode
  out  INTA01, al
  jmp  $+2
  mov  al, 0FFh            ; mask all ints. off
  out  INTA01, al          ; (video routine enables interrupts)
;---------------------------------------------------------
;    re-initialize the 8259 interrupt #2 controller chip  :
;---------------------------------------------------------
  mov  al, 11h             ; icw1 - edge, slave icw4
  out  INTB00, al
  jmp  $+2
  mov  al, INT_TYPE        ; setup icw2 - int type 70 (70-7f)
  out  INTB01, al
  mov  al, 2               ; setup icw3 - slave lv 2
  jmp  $+2
  out  INTB01, al
  jmp  $+2
  mov  al, 1               ; setup icw4 - 8086 mode, slave
  out  INTB01, al
  jmp  $+2
  mov  al, 0FFh            ; mask all ints. off
  out  INTB01, al
;--------------------------------------------------------------------------------

Технический справочник по BIOS (c) 1984 IBM

Примечание:

jmp $+2 ; wait state for i/o не требуется на текущем ПК.

icw1 очищает регистр маски прерываний, который разрешает прерывания на этом PIC.

Чип 8259A давно ушел, но интерфейс программирования все еще используется. 8259A Программируемый контроллер прерываний

...