Triple fault after calling INT 0

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.
Post Reply
yucarp
Member
Member
Posts: 39
Joined: Fri Dec 05, 2025 5:19 pm
Libera.chat IRC: yucarp

Triple fault after calling INT 0

Post by yucarp »

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

Code: Select all

#include <kernel/idt.h>

static struct IDTPointer idt_pointer;
static struct IDTEntry idt_entries[256];

void idt_set_gate(uint8_t n, uint32_t handler, uint16_t selector, uint8_t attributes){
    idt_entries[n].offset_low = (handler & 0xFFFF);
    idt_entries[n].offset_high = ((handler >> 16) & 0xFFFF);
    idt_entries[n].selector = selector;
    idt_entries[n].attributes = attributes;
}

void set_idt(){
    idt_pointer.offset = (uint32_t)(idt_entries);
    idt_pointer.size = sizeof(idt_entries);

    idt_set_gate(0, (uint32_t)_isr0, 0x08, 0x8E);

    asm volatile (
        "lidt %0"
        : : "m"(idt_pointer)
    );
}

void isr_handler(){
    *((char *)(0xB800)) = 'I';
}

Code: Select all

.global _isr0
.type _isr0, @function
_isr0:
    pushl $0
    pushl $0
    jmp isr_common

.extern isr_handler
.type isr_handler, @function

.global isr_common
isr_common:
    pushl %eax
    pushl %ebx
    pushl %ecx
    pushl %edx
    pushl %esi
    pushl %edi
    pushl %ebp
    pushl %esp

    cld
    call isr_handler

    popl %esp
    popl %ebp
    popl %edi
    popl %esi
    popl %edx
    popl %ecx
    popl %ebx
    popl %eax

    add $8, %esp

    iretl
QEMU log:

Code: Select all

     9: v=00 e=0000 i=1 cpl=0 IP=0008:00200072 pc=00200072 SP=0010:00204ff0 env->regs[R_EAX]=00000020
EAX=00000020 EBX=00010000 ECX=00000000 EDX=00000008
ESI=00000000 EDI=00000000 EBP=00204ff8 ESP=00204ff0
EIP=00200072 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0018 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0018 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0018 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     00200006 00000028
IDT=     50000000 00000800
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000 
DR6=ffff0ff0 DR7=00000400
CCS=00000040 CCD=00000020 CCO=SARL
EFER=0000000000000000
check_exception old: 0xffffffff new 0xd
    10: v=0d e=0002 i=0 cpl=0 IP=0008:00200072 pc=00200072 SP=0010:00204ff0 env->regs[R_EAX]=00000020
EAX=00000020 EBX=00010000 ECX=00000000 EDX=00000008
ESI=00000000 EDI=00000000 EBP=00204ff8 ESP=00204ff0
EIP=00200072 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0018 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0018 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0018 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     00200006 00000028
IDT=     50000000 00000800
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000 
DR6=ffff0ff0 DR7=00000400
CCS=00000040 CCD=00000020 CCO=SARL
EFER=0000000000000000
check_exception old: 0xd new 0xd
    11: v=08 e=0000 i=0 cpl=0 IP=0008:00200072 pc=00200072 SP=0010:00204ff0 env->regs[R_EAX]=00000020
EAX=00000020 EBX=00010000 ECX=00000000 EDX=00000008
ESI=00000000 EDI=00000000 EBP=00204ff8 ESP=00204ff0
EIP=00200072 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0018 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0018 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0018 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     00200006 00000028
IDT=     50000000 00000800
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000 
DR6=ffff0ff0 DR7=00000400
CCS=00000040 CCD=00000020 CCO=SARL
EFER=0000000000000000
check_exception old: 0x8 new 0xd
SMM: enter
EAX=00000000 EBX=00000000 ECX=02000000 EDX=02000628
ESI=0000000b EDI=02000000 EBP=00014e40 ESP=00006c5c
EIP=000ea63d EFL=00000046 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     000f61e0 00000037
IDT=     000f621e 00000000
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000 
DR6=ffff0ff0 DR7=00000400
CCS=00000044 CCD=ffffffff CCO=EFLAGS
EFER=0000000000000000
SMM: after RSM
nullplan
Member
Member
Posts: 2034
Joined: Wed Aug 30, 2017 8:24 am

Re: Triple fault after calling INT 0

Post by nullplan »

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.
Carpe diem!
yucarp
Member
Member
Posts: 39
Joined: Fri Dec 05, 2025 5:19 pm
Libera.chat IRC: yucarp

Re: Triple fault after calling INT 0

Post by yucarp »

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.
nullplan
Member
Member
Posts: 2034
Joined: Wed Aug 30, 2017 8:24 am

Re: Triple fault after calling INT 0

Post by nullplan »

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.
Carpe diem!
yucarp
Member
Member
Posts: 39
Joined: Fri Dec 05, 2025 5:19 pm
Libera.chat IRC: yucarp

Re: Triple fault after calling INT 0

Post by yucarp »

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.
sebihepp
Member
Member
Posts: 256
Joined: Tue Aug 26, 2008 11:24 am
GitHub: https://github.com/sebihepp

Re: Triple fault after calling INT 0

Post by sebihepp »

Limit of IDTD must be size-1. I doubt that's the problem right now, but should nevertheless be fixed.

I think we need the contents of idt.h too. Or better: the entire project. A link to github would be nice.
User avatar
iansjack
Member
Member
Posts: 4908
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Triple fault after calling INT 0

Post by iansjack »

Two things you can try:

1. Disassemble your code with objdmp and examine the bit where the lidt instruction is.

2. Step through that part of the code in a debugger to see what’s happening (or isn’t).
yucarp
Member
Member
Posts: 39
Joined: Fri Dec 05, 2025 5:19 pm
Libera.chat IRC: yucarp

Re: Triple fault after calling INT 0

Post by yucarp »

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.

https://github.com/yucarp/ric There is the github for who are interested
nullplan
Member
Member
Posts: 2034
Joined: Wed Aug 30, 2017 8:24 am

Re: Triple fault after calling INT 0

Post by nullplan »

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.
Carpe diem!
yucarp
Member
Member
Posts: 39
Joined: Fri Dec 05, 2025 5:19 pm
Libera.chat IRC: yucarp

Re: Triple fault after calling INT 0

Post by yucarp »

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.
User avatar
DabiiXqx
Posts: 11
Joined: Sun Feb 15, 2026 12:06 am
Libera.chat IRC: dabii

Re: Triple fault after calling INT 0

Post by DabiiXqx »

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.

May i have the code please?
yucarp
Member
Member
Posts: 39
Joined: Fri Dec 05, 2025 5:19 pm
Libera.chat IRC: yucarp

Re: Triple fault after calling INT 0

Post by yucarp »

I have abandoned that project in order to work a new one but the old project can be found in https://github.com/yucarp/ric/tree/main
User avatar
DabiiXqx
Posts: 11
Joined: Sun Feb 15, 2026 12:06 am
Libera.chat IRC: dabii

Re: Triple fault after calling INT 0

Post by DabiiXqx »

thank you
Post Reply