The problem in short: I have written an ISR for interrupt 0 (divide by zero exception). I have made an interrupt descriptor for it, I have made an IDT in memory, and I have a pointer to that IDT. I hand the pointer over to the lidt instruction. I can breakpoint near the lidt instruction and confirm that the idtr shows the base and limit as I expect it to. I divide by zero and, rather than running my ISR, Bochs appears to immediately reset. The kernel's address base is 0xf0000000 and I am not currently using paging. I am using packing pragmas on my IDT-related structs and I have confirmed their size to be correct.
My IDT-manipulating functions are as follows:
Code: Select all
void reset_idt() {
memset(idt, 0, sizeof(IDTDescr)*256);
idt_struct.base = (uint32_t)idt;
idt_struct.limit = 256*(sizeof(IDTDescr)-1);
idtp = &idt_struct;
}
void set_idt_entry(uint8_t number, void (*handler)(), uint16_t type) {
uint32_t handler_addr = (uint32_t)handler;
idt[number].offset_1 = LOW_OFFSET(handler_addr);
idt[number].offset_2 = HIGH_OFFSET(handler_addr);
idt[number].selector = GD_KT;
idt[number].type_attr = type;
idt[number].zero = 0;
}
void load_idt() {
asm volatile("LIDT (%0) ": :"p" (idtp));
asm("cli");
}
I don't know what I should check next. Any thoughts?