ובכן, לאחר סוגריים קטנים אנו ממשיכים בסדרת ההדרכות שלנו. אם נחזור לקוד הקודם עלינו לאפס את ה- ISR של החלוקה. כעת עלינו למלא את שאר ה- ISR עבורם פרסמנו (32 הראשונים). ובכן, כעת אנו נמשיך להפריע לתכנות, אנו נבצע את ה- IRQ המכונה גם קוטע בקשות. IRQ אלה נוצרים על ידי התקני חומרה כגון מקלדות, עכברים, מדפסות וכו '. בתחילה שמונות ה- IRQ הראשונות ממופות אוטומטית למיקומי IDT 8 עד 8. מכיוון שהשתמשנו ב -15 הראשונים למעט חריגים כעת עלינו למפות אותם מחדש. אנו מכניסים את ה- IRQ מ- 32 ל- 32. לשם כך עלינו למפות תחילה את ה- IRQ:
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);
}
כעת אנו יוצרים פונקציה להתקנת ה- IRQ:
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");
}
המשפט של אסם Sti אנו מפעילים את ה- IRQ. ובכן עכשיו אנחנו הולכים עם משהו דומה ל- ISR. הפונקציות של IRQ בסיסי:
void ND::IRQ::IRQ1()
{
asm volatile(
"cli \n"
"pushl 0\n"
"pushl 32\n"
"jmp ND_IRQ_Common"
);
}
חלק נפוץ (זהה ל- 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"
);
}
ומטפל בסיסי:
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);
}
עם זאת עלינו כבר להפעיל את ה- IRQ גם אם הם עדיין לא עושים דבר. בפרק הבא נראה כיצד להשיג נתונים מ- IRQ אלה כגון השעון או המקלדת.
ועם זה מסתיים ההודעה של היום. כפי שאתה יכול לראות עכשיו אני כותב פחות בקביעות בגלל בעיות אחרות. למרות זאת אמשיך עד שתהיה לי מערכת הפעלה שלמה יותר