Hi Leute,
ich habe schon wieder ein Problem. Ich wollte einen IRQ-Manager programmieren. Als Basis habe ich diese Tuts genommen http://www.osdever.net/bkerndev/Docs/irqs.htm und http://lowlevel.brainsware.org/wiki/index.php/ISR. Und hier habe ich auch schon eine Frage. Wieso wird in dem Tut von osdev mit cli die Interrupts ab, aber nicht wieder angeschaltet? Bei dem von lowlevel wird gar nichts deaktiviert. Ich habe mir dann mal folgenden Code geschrieben.
Kernel.c
Ich hoffe ihr könnt mir helfen. Vielen dank schon mal.
ich habe schon wieder ein Problem. Ich wollte einen IRQ-Manager programmieren. Als Basis habe ich diese Tuts genommen http://www.osdever.net/bkerndev/Docs/irqs.htm und http://lowlevel.brainsware.org/wiki/index.php/ISR. Und hier habe ich auch schon eine Frage. Wieso wird in dem Tut von osdev mit cli die Interrupts ab, aber nicht wieder angeschaltet? Bei dem von lowlevel wird gar nichts deaktiviert. Ich habe mir dann mal folgenden Code geschrieben.
Kernel.c
Code: [Auswählen]
// Test for Irq
void IRQ0_Test(struct SIRQParam Param)
{
kprintf("IRQ 0", 0, 10);
DeleteIRQHandler(0);
kprintf("IRQ0-handler deleted", 0, 12);
}
IRQ.cCode: [Auswählen]
// Defines
#define PCI1 0x20
#define PCI2 0xA0
#define PCI1_DATA (PCI1 + 1)
#define PCI2_DATA (PCI2 + 1)
#define PCI1_VECTOR 0x20
#define PCI2_VECTOR 0x28
// The 16 IRQ-functions (they are in IRQ.asm)
extern void IRQ0();
extern void IRQ1();
extern void IRQ2();
extern void IRQ3();
extern void IRQ4();
extern void IRQ5();
extern void IRQ6();
extern void IRQ7();
extern void IRQ8();
extern void IRQ9();
extern void IRQ10();
extern void IRQ11();
extern void IRQ12();
extern void IRQ13();
extern void IRQ14();
extern void IRQ15();
// The IRQHandler
void* IRQHandlers[16] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
// Remap the entries
void Remap()
{
// Start the init process
OutPort(PCI1, 0x11);
OutPort(PCI2, 0x11);
// Remap the entries
OutPort(PCI1_DATA, 0x20);
OutPort(PCI2_DATA, 0x28);
OutPort(PCI2_DATA, 0x04);
OutPort(PCI1_DATA, 0x02);
OutPort(PCI2_DATA, 0x01);
OutPort(PCI1_DATA, 0x01);
OutPort(PCI2_DATA, 0x00);
OutPort(PCI1_DATA, 0x00);
}
// Init IRQ
int IRQInit()
{
// Remap the IRQ entries
Remap();
// Set the IRQ-Functions
IDTSetEntry(32, (unsigned long) IRQ0, 0x08, 0x8E);
IDTSetEntry(33, (unsigned long) IRQ1, 0x08, 0x8E);
IDTSetEntry(34, (unsigned long) IRQ2, 0x08, 0x8E);
IDTSetEntry(35, (unsigned long) IRQ3, 0x08, 0x8E);
IDTSetEntry(36, (unsigned long) IRQ4, 0x08, 0x8E);
IDTSetEntry(37, (unsigned long) IRQ5, 0x08, 0x8E);
IDTSetEntry(38, (unsigned long) IRQ6, 0x08, 0x8E);
IDTSetEntry(39, (unsigned long) IRQ7, 0x08, 0x8E);
IDTSetEntry(40, (unsigned long) IRQ8, 0x08, 0x8E);
IDTSetEntry(41, (unsigned long) IRQ9, 0x08, 0x8E);
IDTSetEntry(42, (unsigned long) IRQ10, 0x08, 0x8E);
IDTSetEntry(43, (unsigned long) IRQ11, 0x08, 0x8E);
IDTSetEntry(44, (unsigned long) IRQ12, 0x08, 0x8E);
IDTSetEntry(45, (unsigned long) IRQ13, 0x08, 0x8E);
IDTSetEntry(46, (unsigned long) IRQ14, 0x08, 0x8E);
IDTSetEntry(47, (unsigned long) IRQ15, 0x08, 0x8E);
// Enable the IRQ
asm volatile("sti");
// All was success
return 1;
}
// This function set an IRQHandler
void SetIRQHandler(void *pFunction, const unsigned int iIRQIndex)
{
IRQHandlers[iIRQIndex] = pFunction;
}
// This function delete an IRQHandler
void DeleteIRQHandler(const unsigned int iIRQIndex)
{
IRQHandlers[iIRQIndex] = 0;
}
// The IRQ-Handler which is called in IRQ.asm
void IRQHandler(struct SIRQParam Param)
{
// Call the IRQ-Handler
void (*pIRQHandler) (struct SIRQParam);
if (IRQHandlers[Param.iIRQ] != NULL)
{
pIRQHandler = IRQHandlers[Param.iIRQ];
pIRQHandler(Param);
}
// Tell the PCI that we finished with the interrupt
if (Param.iIRQ >= 8)
OutPort(PCI2, 0x20);
OutPort(PCI1, 0x20);
}
IRQ.asmCode: [Auswählen]
........
IRQ15:
cli
push byte 15
jmp IRQ_HANDLER
; The IRQ-Handler
extern IRQHandler
IRQ_HANDLER:
; Make sure that we are working with kernel privilegs
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
; Call the c-Handler
call IRQHandler
iret
Er funktioniert aber nicht richtig. Der IRQ-Handler aus Kernel.c wird zwar ausgerufen, aber sobald der IRQ-Manager diese Interrupt fertig bearbeitet hat, gibt es einen Reboot. Warum? Was habe ich falsch gemacht?Ich hoffe ihr könnt mir helfen. Vielen dank schon mal.

Übersicht
Wiki
Hilfe
Suche
Einloggen
Registrieren
Drucken

Gespeichert