2008-11-12 85 views
9

我正在学习几个教程和参考,试图让我的内核设置。我在教程中遇到了一些不熟悉的代码,根本没有解释它。这是我听说代码映射16 IRQs (0-15)到ISR位置32-47设置IRQ映射

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架构上。这个源代码工作正常,我明白它的作用,但我不明白它是如何做到的。有人能向我解释这里发生了什么事情,所以如果我需要扩展这个,我会知道我在做什么?

回答

12

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/,这是一个新的业余爱好OS开发人员的宝贵资源。

+0

哇,这正是我所需要的。谢谢一束! – 2008-11-12 04:45:49

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(三)1984年IBM

注:

jmp $+2 ; wait state for i/o不需要当前PC上。

icw1清除中断屏蔽寄存器,该寄存器启用该PIC上的中断。

8259A芯片早已消失,但仍然使用编程接口。 8259A Programmable Interrupt Controller