Configurando o mapeamento de IRQ
Pergunta
Eu estou seguindo vários tutoriais e referências tentando se meu kernel configurar. Eu vim através de algum código desconhecido em um tutorial que não é explicá-lo em tudo. código É que eu sou dito mapeia o 16 IRQs (0-15)
para locais 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);
}
O código para outportb()
como se segue, mas eu já tenho uma compreensão clara do que seu fazer:
void outPortB(unsigned short port, unsigned char data)
{
__asm__ __volatile__ ("outb %1, %0" : : "dN" (port), "a" (data));
}
Eu devo mencionar que esta é na arquitetura x86 em modo protegido. Este código-fonte funciona bem e eu entendo o que ele faz, mas eu não entendo como ele faz isso. Alguém pode me explicar o que está acontecendo aqui, para que no caso eu preciso expandir essa eu vou saber o que estou fazendo?
Solução
outb
e similares, escreva para hardware portas IO. Basicamente, existem 2 opções principais para se comunicar com um dispositivo. Você pode ter o dispositivo mapeado para portas de memória ou IO.
Quanto à forma como funciona este código, eu vou comentar isso para você:
ICW significa "Inicialização Comandos Palavras"
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 isso ajude
Bem-vindo ao mundo do OS dev :) Eu também recomendo que você visite: http: //forum.osdev. org / , é um recurso inestimável para um novo desenvolvedor OS hobby.
Outras dicas
A resposta simples é que em modo protegido as interrupções usadas pelo 1º Controlador de interrupção programável são exceções modo protegido, o que significa que eles têm de ser remapeado.
A resposta feliz é que somente as primeiras necessidades PIC
para ser remapeado (o remapeamento do segundo é apenas por conveniência, uma vez que começa no int 70h
).
Aqui está uma citação do BIOS AT originais.
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
;--------------------------------------------------------------------------------
Technical Reference AT BIOS (c) 1984 IBM
Nota:
O jmp $+2 ; wait state for i/o
não é necessária em um PC atual.
O icw1
limpa o registro da máscara de interrupção, o que permite que as interrupções em que PIC.
O chip 8259A é muito que desapareceu, mas a interface de programação ainda é usado. 8259A Controlador de interrupção programável