Linu Torvaldsin jäljitteleminen: Luo oma käyttöjärjestelmäsi tyhjästä (VI)

Okei, lyhyen tauon jälkeen jatketaan tutoriaalisarjaamme. Jos palaamme edelliseen koodiin, meillä pitäisi olla ISR nollalla jakamista varten. Nyt meidän on täytettävä loput ISR:t, joille aiemmin asetimme viestin (ensimmäiset 32). Nyt jatkamme keskeytysten ohjelmointia; luomme IRQ:ita, jotka tunnetaan myös keskeytyspyyntöinä. Nämä IRQ:t generoivat laitteet, kuten näppäimistöt, hiiret, tulostimet jne. Aluksi ensimmäiset 8 IRQ:ta kartoitetaan automaattisesti IDT-paikkoihin 8–15. Koska käytimme ensimmäisiä 32 poikkeuksiin, meidän on nyt kartoitettava ne uudelleen. Määritämme IRQ:t väliltä 32–45. Tätä varten meidän on ensin kartoitettava IRQ:t uudelleen:

void ND::IRQ::Remap(int pic1, int pic2)
{
#define PIC1 0x20
#define PIC2 0xA0
#define ICW1 0x11
#define ICW4 0x01
/* send ICW1 */
ND::Ports::OutputB(PIC1, ICW1);
ND::Ports::OutputB(PIC2, ICW1);
/* send ICW2 */
ND::Ports::OutputB(PIC1 + 1, pic1); /* remap */
ND::Ports::OutputB(PIC2 + 1, pic2); /* pics */
/* send ICW3 */
ND::Ports::OutputB(PIC1 + 1, 4); /* IRQ2 -> connection to slave */
ND::Ports::OutputB(PIC2 + 1, 2);
/* send ICW4 */
ND::Ports::OutputB(PIC1 + 1, ICW4);
ND::Ports::OutputB(PIC2 + 1, ICW4);
/* disable all IRQs */
ND::Ports::OutputB(PIC1 + 1, 0xFF);
}

Nyt luomme toiminnon IRQ: iden asentamiseksi:

void ND::IRQ::Install()
{
ND::Screen::SetColor(ND_SIDE_FOREGROUND,ND_COLOR_BLACK);
ND::Screen::PutString("\nInstalling IRQ...");
ND::IRQ::Remap(0x20,0x28);
ND::IDT::SetGate(32,(unsigned)ND::IRQ::IRQ1,0x08,0x8E);
ND::IDT::SetGate(33,(unsigned)ND::IRQ::IRQ2,0x08,0x8E);
ND::IDT::SetGate(34,(unsigned)ND::IRQ::IRQ3,0x08,0x8E);
ND::IDT::SetGate(35,(unsigned)ND::IRQ::IRQ4,0x08,0x8E);
ND::IDT::SetGate(36,(unsigned)ND::IRQ::IRQ5,0x08,0x8E);
ND::IDT::SetGate(37,(unsigned)ND::IRQ::IRQ6,0x08,0x8E);
ND::IDT::SetGate(38,(unsigned)ND::IRQ::IRQ7,0x08,0x8E);
ND::IDT::SetGate(39,(unsigned)ND::IRQ::IRQ8,0x08,0x8E);
ND::IDT::SetGate(40,(unsigned)ND::IRQ::IRQ9,0x08,0x8E);
ND::IDT::SetGate(41,(unsigned)ND::IRQ::IRQ10,0x08,0x8E);
ND::IDT::SetGate(42,(unsigned)ND::IRQ::IRQ11,0x08,0x8E);
ND::IDT::SetGate(43,(unsigned)ND::IRQ::IRQ12,0x08,0x8E);
ND::IDT::SetGate(44,(unsigned)ND::IRQ::IRQ13,0x08,0x8E);
ND::IDT::SetGate(45,(unsigned)ND::IRQ::IRQ14,0x08,0x8E);
ND::IDT::SetGate(46,(unsigned)ND::IRQ::IRQ15,0x08,0x8E);
ND::IDT::SetGate(47,(unsigned)ND::IRQ::IRQ16,0x08,0x8E);
ND::Screen::SetColor(ND_SIDE_FOREGROUND,ND_COLOR_GREEN);
ND::Screen::PutString("done");
asm volatile("sti");
}

Asm. Lause sti aktivoimme IRQ: t. No, nyt menemme jotain vastaavaa kuin ISR. IRQ: n perustoiminnot:

void ND::IRQ::IRQ1()
{
asm volatile(
"cli \n"
"pushl 0\n"
"pushl 32\n"
"jmp ND_IRQ_Common"
);
}

Yhteinen osa (sama kuin ISR):

extern "C"
void ND_IRQ_Common()
{
asm volatile(
"pusha \n"
"push %ds\n"
"push %es\n"
"push %fs\n"
"push %gs\n"
"movw $0x10, %ax \n"
"movw %ax, %ds \n"
"movw %ax, %es \n"
"movw %ax, %fs \n"
"movw %ax, %gs \n"
"movl %esp, %eax \n"
"push %eax \n"
"movl $ND_IRQ_Handler, %eax \n"
"call *%eax \n"
"popl %eax \n"
"popl %ds \n"
"popl %es \n"
"popl %fs \n"
"popl %gs \n"
"popa \n"
"addl 8, %esp \n"
"iret \n"
);
}

Ja peruskäsittelijä:

extern "C"
void ND_IRQ_Handler(struct regs* r)
{
void (*handler)(struct regs *r);
if(r->int_no >= 40)
{
ND::Ports::OutputB(0xA0,0x20);
}
ND::Ports::OutputB(0x20,0x20);
}

Tällöin IRQ pitäisi jo olla aktivoituna, vaikka he eivät vieläkään tee mitään. Seuraavassa luvussa nähdään, miten tietoja saadaan näistä IRQ-laitteista, kuten kellosta tai näppäimistöstä.

SeuraavaDivel-IRQ


Ja tämä päättyy tämän päivän viesti. Kuten näette nyt, kirjoitan vähemmän säännöllisesti muista asioista johtuen. Silti jatkan, kunnes minulla on täydellisempi käyttöjärjestelmä


Lisää ensisijaiseksi lähteeksi Googlessa