2008-11-12 8 views
9

Estoy siguiendo varios tutoriales y referencias tratando de configurar mi kernel. Me encontré con un código desconocido en un tutorial que no lo explica en absoluto. Es el código que me han dicho mapea la 16 IRQs (0-15) al ISR lugares 32-47:Configuración de mapeo 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); 
} 

El código para outportb() es el siguiente, pero ya tengo una idea clara de lo que lo haga:

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

I debería mencionar que esto es en la arquitectura x86 en modo protegido. Este código fuente funciona bien y entiendo lo que hace, pero no entiendo cómo lo hace. ¿Puede alguien explicarme qué está pasando aquí, de modo que en caso de que necesite ampliar esto sabré lo que estoy haciendo?

Respuesta

12

outb y análogos, escriba en el hardware de puertos IO. Básicamente, hay 2 opciones principales para comunicarse con un dispositivo. Puede hacer que el dispositivo se asigne a la memoria o a los puertos IO.

En cuanto a cómo funciona este código, que voy a comentar por usted:

representa ICW "Comandos de inicialización Las palabras"

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 */ 

espero que esto ayude

Bienvenido al mundo de Desarrollador de SO :) También recomiendo que visites: http://forum.osdev.org/, es un recurso invaluable para un nuevo desarrollador de SO de hobby.

+0

Guau, eso es exactamente lo que necesitaba. ¡Gracias, racimos! –

1

La respuesta simple es que en el modo protegido, las interrupciones utilizadas por el 1er. Controlador de interrupción programable son excepciones de modo protegido, lo que significa que deben ser reasignadas.

La respuesta feliz es que sólo los primeros PIC necesidades que se reasignan (la reasignación de la segunda sólo por conveniencia, ya que comienza en int 70h). Aquí hay una cita del AT BIOS original.

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 
;-------------------------------------------------------------------------------- 

Referencia Técnica AT BIOS (c) 1984 IBM

Nota:

El jmp $+2 ; wait state for i/o no se requiere en un PC actual.

El icw1 borra el registro de la máscara de interrupción, que habilita las interrupciones en ese PIC.

El chip 8259A hace tiempo que se fue pero la interfaz de programación todavía se usa. 8259A Programmable Interrupt Controller