设置中断请求映射

9

我正在学习一些教程和参考资料,试图设置我的内核。在一个教程中,我遇到了一些不熟悉的代码,而且教程并没有解释它。我被告知这段代码将 16个IRQ(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个回答

15

outb和类似的指令用于向硬件IO端口写入数据。基本上,与设备通信有两个主要选项。可以将设备映射到内存或IO端口。

至于这段代码的工作原理,我会为您加上注释:

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
简单来说,在保护模式下,第一个可编程中断控制器使用的中断是受保护模式异常,这意味着它们需要重新映射。

令人高兴的是,只有第一个 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
;--------------------------------------------------------------------------------

技术参考 AT BIOS (c) 1984 IBM

注意:

在当前的 PC 上,jmp $+2; wait state for i/o 不是必需的。

icw1 清除中断屏蔽寄存器,从而使该 PIC 上的中断有效。

8259A 芯片早已消失,但编程接口仍在使用。 8259A 可编程中断控制器


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接