2008-11-12 110 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