2008-11-12 30 views
9

Je suis plusieurs didacticiels et références essayant de configurer mon noyau. J'ai rencontré un code peu familier dans un tutoriel qui ne l'explique pas du tout. Il est le code que je suis dit mappe le 16 IRQs (0-15) aux ISR emplacements 32-47:Configuration du mappage 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); 
} 

Le code pour outportb() est la suivante, mais j'ai déjà une compréhension claire de ce que son fait:

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

I devrait mentionner que c'est sur l'architecture x86 en mode protégé. Ce code source fonctionne bien et je comprends ce qu'il fait, mais je ne comprends pas comment il le fait. Quelqu'un peut-il m'expliquer ce qui se passe ici, au cas où je devrais m'étendre là-dessus, je saurai ce que je fais?

Répondre

12

outb et similaire, écrire sur les ports d'E/S matériels. Fondamentalement, il existe 2 options principales pour communiquer avec un appareil. Vous pouvez faire correspondre le périphérique à la mémoire ou aux ports d'E/S.

En ce qui concerne la façon dont ce code fonctionne, je vais commenter pour vous:

ICW signifie "Initialisation Commandes mots"

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

this helps

Bienvenue dans le monde de OS dev :) Je vous recommande également de visiter: http://forum.osdev.org/, c'est une ressource inestimable pour un nouveau développeur OS de passe-temps.

+0

Wow, c'est exactement ce dont j'avais besoin. Merci les régimes! –

1

La réponse simple est qu'en mode protégé, les interruptions utilisées par le 1er contrôleur d'interruption programmable sont des exceptions en mode protégé, ce qui signifie qu'elles doivent être remappées.

La réponse est heureuse que seuls les premiers PIC besoins à reconfigurés (le remappage du second est que pour la commodité, car il commence à int 70h). Voici une citation de l'original 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 
;-------------------------------------------------------------------------------- 

Référence technique AT BIOS (c) 1984 IBM

Note:

Le jmp $+2 ; wait state for i/o n'est pas nécessaire sur un PC en cours.

Le icw1 efface le registre de masque d'interruption, ce qui active les interruptions sur ce PIC.

La puce 8259A a disparu depuis longtemps mais l'interface de programmation est toujours utilisée. 8259A Programmable Interrupt Controller