Page 1 of 1

IDT multiple call bug

Posted: Sun Sep 17, 2023 7:15 am
by leventkaya
hello, i am quite a beginner of OSDev, i am tring to build my first os, and i have implemented my IDT just regular basic stuff that every OS have. Nothing special. And then i try to trigger an zero division interrupt the i see my kernel calls the idt_zero exception in a endless loop. here is my implemetation.

idt.c:

Code: Select all

#include "../include/idt.h"

idt_t idt[ARTILLERYOS_MAX_INTERRUPT_SIZE];
idt_ptr_t idt_ptr;

extern void idt_load(idt_ptr_t *ptr);
static int handled = 0;
void idt_zero()
{
	if (handled == 0) {
		terminal_print("\n div error");
		handled = 1;
	}
}

void idt_set(int interrupt_no, void *address)
{
	idt_t *desc = &idt[interrupt_no];
	uint32_t addr = (uint32_t)address;

	desc->offset_1 = addr & 0xFFFF;
	desc->selector = KERNEL_CODE_SELECTOR;
	desc->zero = 0x00;
	desc->type_attr = 0xEE;
	desc->offset_2 = (addr >> 16) & 0xFFFF;
}

void idt_init()
{
	memset(idt, 0, sizeof(idt));
	idt_ptr.limit = sizeof(idt) - 1;
	idt_ptr.base = (uint32_t)idt;

	idt_set(0, idt_zero);

	idt_load(&idt_ptr);
}

idt.asm:

Code: Select all

section .asm

global idt_load
idt_load:
    push ebp
    mov ebp, esp

    mov ebx, [ebp+8]
    lidt [ebx]
    pop ebp
    ret

then I am crating a problem in my kernel.asm:

Code: Select all

problem:
    mov eax, 0
    div eax
the kernel actually works and prints the division by zero error on screen but i expected to print it once. My kernel is calling the idt_zerro for ever. I'm tried to debug but cant find any error prone code. It would be nice to guadience. Also i am sharing a screen shot too on attachments.

Re: IDT multiple call bug

Posted: Sun Oct 15, 2023 8:49 am
by proto639
I think interrupt handlers need to be written in assembly, your code might be missing an iret. I think GCC has a special attribute for interrupts or something but I don't know it that well
It might also be going back to the faulty code triggering an infinite loop, constantly dividing by zero

Re: IDT multiple call bug

Posted: Sun Oct 15, 2023 11:45 am
by nullplan
proto639 wrote:I think interrupt handlers need to be written in assembly, your code might be missing an iret. I think GCC has a special attribute for interrupts or something but I don't know it that well
It might also be going back to the faulty code triggering an infinite loop, constantly dividing by zero
Yeah, pretty much that. By registering a normal function as exception handler, you never save all registers. You also return with a normal ret instead of iret, which in turn returns to the faulting instruction. There will likely be a stack overflow at some point (because you never clear the entire interrupt frame) and that will probably fault in a different way. Not quite sure why static variables aren't working for you, though.

I'd suggest that for now, you handle all exceptions by printing what exception happened and the return IP, then halting. This will ease debugging.

Re: IDT multiple call bug

Posted: Sun Oct 15, 2023 3:23 pm
by proto639
nullplan wrote:
proto639 wrote:I think interrupt handlers need to be written in assembly, your code might be missing an iret. I think GCC has a special attribute for interrupts or something but I don't know it that well
It might also be going back to the faulty code triggering an infinite loop, constantly dividing by zero
Yeah, pretty much that. By registering a normal function as exception handler, you never save all registers. You also return with a normal ret instead of iret, which in turn returns to the faulting instruction. There will likely be a stack overflow at some point (because you never clear the entire interrupt frame) and that will probably fault in a different way. Not quite sure why static variables aren't working for you, though.

I'd suggest that for now, you handle all exceptions by printing what exception happened and the return IP, then halting. This will ease debugging.
Yeah, I also looked more into the interrupt attribute and found it here:
https://gcc.gnu.org/onlinedocs/gcc/x86- ... e_002c-x86
you could try appending the attribute to your handler function, I haven't personally used this so I cannot say for certain if it will work