0

Ich bin nicht in der Lage, IDT arbeiten, weil meine Interrupt-Routinen nicht aufgerufen werden, vor allem die Tastatur verwandt, wenn ich eine Taste auf der Tastatur drücken. Ich übergebe die spezielle 48-Bit-Zeigeradresse der IDT-Tabelle. Ich mache es wieIDT in C funktioniert nicht

Ich weiß auch nicht, ob mindestens GDT funktioniert oder nicht.

1) Was soll ich tun, damit mein IDT funktioniert? Ich sah auch ein paar Tutorials, aber es half nicht 2) Wie kann ich überprüfen, ob GDT richtig funktioniert?

Vielen Dank im Voraus.

EDIT: Ich mache das für mein eigenes Betriebssystem. Ich bin zweifelhaft, ob meine Montage-Routine die Adresse des Zeigers richtig empfangen kann. Also habe ich auch versucht, lidt mit Inline-Assembly zu tun, aber hat nicht geholfen. Ich weiß nicht, was falsch ist. Irgendwelche Hinweise, Idee?

void remap_irqs(void) 
{ 
outb(0x20, 0x11); 
outb(0xA0, 0x11); 
outb(0x21, 0x20); 
outb(0xA1, 0x28); 
outb(0x21, 0x04); 
outb(0xA1, 0x02); 
outb(0x21, 0x01); 
outb(0xA1, 0x01); 
outb(0x21, 0x0); 
outb(0xA1, 0x0); 
outbyte('a'); 

}

void set_idt_gate(uint8 num, unsigned long base, word sel, uint8 flags) 
{ 
IDT[num].offset_low = (base & 0xFFFF); 
IDT[num].offset_high = (base >> 16) & 0xFFFF;  
IDT[num].selector = sel;  
IDT[num].zero = 0; 
IDT[num].type_attrs = flags; 
} 




void init_idt() 
{ 
outbyte('M'); 
idt_ptr.limit = (sizeof (idt_entry) * 256) - 1; 
idt_ptr.base =(uint32) &IDT; 

memset((uint8 *)&IDT, 0, sizeof(idt_entry) * 256); 
remap_irqs(); 
set_idt_gate(0, (unsigned) irq_0, 0x08, 0x8E); 
set_idt_gate(1, (unsigned) irq_1, 0x08, 0x8E); 
//install_isrs(); 
//install_irqs(); 
//idt_load(); 
//print_message(); 
lidt(&IDT,idt_ptr.limit); 
_LIDT(&idt_ptr); 
loadidt(&idt_ptr); 
} 



void lidt(void * base, unsigned short size) 
{ 
struct 
{ 
    unsigned short length; 
    unsigned long base; 
} __attribute__((__packed__)) IDTR; 

IDTR.length = size; 
IDTR.base = (unsigned long)base; 
asm("lidt (%0)" 
    : : "p"(&IDTR)); 

}

void _LIDT(dt_ptr *ptr) 
{ 
asm("lidt (%0)" : :"p"(ptr)); 
outbyte('n'); 
} 





void irq_0() 
{ 
//before_interrupt(); 
ticks+=1; 
if(ticks%18==0) 
{ 
    outbyte('+'); 
    outbyte('1'); 
} 
//after_interrupt(); 
} 

void irq_1() 
{ 
outbyte('a'); 
//before_interrupt(); 
irq1_keyb(); 
//after_interrupt(); 
} 

typedef struct { 
uint16 offset_low; // The lower 16 bits of the address to jump to when this 
interrupt occures:// offset 0-15 
uint16 selector;  // Kernel segment selector in IDT 
uint8 zero;   // This must always be zero. 
uint8 type_attrs; //gate types, atttribute types etc. 
uint16 offset_high; // The upper 16 bits of the address to jump to. offset 16-31 
} __attribute__((__packed__)) idt_entry; 


typedef struct { 
uint16 limit; 
uint32 base;  // The address of the first element in IDT array. 
} __attribute__((__packed__)) dt_ptr; 


global loadidt 
loadidt: 
push ebp 
mov ebp,esp  
mov eax,[ebp+8]  
lidt [eax]  
pop ebp  
ret 
+3

Für Interrupt-Probleme wäre es hilfreich, Ihr zu sagen, Plattform und vielleicht Ihr Betriebssystem – Matthias

+0

Mein eigenes Betriebssystem – geek1000

+0

... und Ihre Plattform (dh, welcher Prozessor, und im Falle von Interrupt-Überlegungen, Controller, falls vorhanden) – Matthias

Antwort

1

Sie setzen IRQs Vektor 0x20 versetzt. Das bedeutet, dass IRQ0 dem Interrupt 0x20, IRQ1 zugeordnet ist, um 0x21 usw. zu unterbrechen. Sie haben jedoch festgelegt, dass Ihre IRQ-Handler ausgeführt werden, wenn die Interrupts 0x00 und 0x01 auftreten. Das ist, wie Sie IDR setzen soll.

set_idt_gate(0x20, (unsigned) irq_0, 0x08, 0x8E); 
set_idt_gate(0x21, (unsigned) irq_1, 0x08, 0x8E); 

Sie weitere Informationen über PIC finden here (Abschnitt Initialisierung erklärt genau, was Sie in remap_irqs Funktion tun

+0

danke. Etwas kann mit gdt falsch sein. als Ganzes keine Verbesserung. – geek1000