Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
I am trying to set the IDT right now and this issue baffles me. Loading the IDT works correctly and the GDT is working too as I can do a long jump. I am also sure that all registers are pushed and popped. The structure of table entries are also correct if I didn't miss anything. EDIT: I found out that the IDT pointer isn't actually loaded but I don't know why
I suspect you failed to declare you struct IDTPointer with the "packet" attribute. This causes the data to not be in the right place for the "lidt" instruction.
nullplan wrote: ↑Sat Dec 06, 2025 8:05 am
I suspect you failed to declare you struct IDTPointer with the "packet" attribute. This causes the data to not be in the right place for the "lidt" instruction.
Nope, after trying packaging the pointers it still triple faults with the same errors.
Well, whatever the case, the error is not anywhere in the code you have posted, and you already know that the IDTR contents are wrong, so you need to figure out what data exactly you are giving to the LIDT instruction. It's supposed to be a two-byte value containing the IDT limit, followed by a 4 byte value containing the base pointer, with no padding in between.
Well, I checked it a lot and the size of the IDT pointer was always 6. I have also checked if I was giving the address instead of pointer but it didn't help too. It's really mysterious, everything seems right but it always gives the same fault.
Well, I noticed something weird, there is no ".data" section in the kernel executable. When I try to put the GDT into the data section it suddenly stops being a valid multiboot executable. Neither the pointer I put and the IDT table is in the executable. Don't mind the crude GDT table with only kernel segments, it's only for testing.
You have no .data section because you have no initialized data. There is no issue with this. The IDT is in the .bss section, so doesn't need to be in the executable.
I tried to find what the problem might be, but I don't see the issue. According to the disassembler, the IDTR should be set correctly. And indeed when I run it in QEMU, I get output saying the IDTR is loaded correctly. However, the interrupt is happening at PC=0008:00000207, which is not in the kernel binary at all. No, it seems like your interrupt gate is incorrect, and the interrupt instruction sends the execution off into the woods.
Thank you so much! It worked after setting the gate setter function to take a void pointer instead of a converted uint32_t and doing a shift operation instead of an and operation to get the higher portion of the offset. I don't know why it happened but probably the pointer got altered in the function.
yucarp wrote: ↑Sun Dec 07, 2025 9:27 am
Thank you so much! It worked after setting the gate setter function to take a void pointer instead of a converted uint32_t and doing a shift operation instead of an and operation to get the higher portion of the offset. I don't know why it happened but probably the pointer got altered in the function.