Page 1 of 2

Triple Fault when a key is pressed

Posted: Fri Mar 05, 2021 9:16 pm
by catOS
Hello World,

I've been working on interrupts in my OS so I can handle keyboard input but so far it hasn't been working. When I press a key it reboots (a triple fault most likely, correct me if i'm wrong). I've looked at my code over and over again but I cannot find the bug. I know that problems with interrupts on this forum are quite common, so I'm wondering if this is a common issue. I can't provide much debugging details because of the lack of exceptions (due to interrupts being a precondition for exceptions).

Related code:
idt.cpp - https://github.com/ackOS-project/dev/bl ... es/idt.cpp
interrupts.cpp - https://github.com/ackOS-project/dev/bl ... rrupts.cpp
irq.asm - https://github.com/ackOS-project/dev/bl ... es/irq.asm
pic_8259.asm - https://github.com/ackOS-project/dev/bl ... c_8259.cpp

Help would be much appreciated.

Re: Triple Fault when a key is pressed

Posted: Fri Mar 05, 2021 9:38 pm
by Gigasoft
You forgot to set the Present bit in your IDT entries.

Re: Triple Fault when a key is pressed

Posted: Fri Mar 05, 2021 9:57 pm
by Octocontrabass
catOS wrote:I can't provide much debugging details
Which virtual machine are you using? Most of them have built-in debugging tools that can tell you more about the fault.

Re: Triple Fault when a key is pressed

Posted: Fri Mar 05, 2021 11:17 pm
by catOS
Octocontrabass wrote: Which virtual machine are you using? Most of them have built-in debugging tools that can tell you more about the fault.
qemu. I tried debugging with gdb but unfortunately I'm not getting very good results.

Image

Re: Triple Fault when a key is pressed

Posted: Fri Mar 05, 2021 11:30 pm
by Octocontrabass
Perhaps try QEMU's interrupt log instead. Add "-d int" and "-no-reboot" to your QEMU command line and you should see register dumps from every interrupt, including the exceptions that lead to the triple fault. (You may need to disable hardware acceleration too.)

You might also look at the QEMU monitor. It has several commands for dumping the CPU's control registers and structures in a human-readable format, which might help you spot issues depending on the exceptions you're getting.

Re: Triple Fault when a key is pressed

Posted: Sat Mar 06, 2021 1:46 am
by catOS
Octocontrabass wrote:Perhaps try QEMU's interrupt log instead. Add "-d int" and "-no-reboot" to your QEMU command line and you should see register dumps from every interrupt, including the exceptions that lead to the triple fault. (You may need to disable hardware acceleration too.)

You might also look at the QEMU monitor. It has several commands for dumping the CPU's control registers and structures in a human-readable format, which might help you spot issues depending on the exceptions you're getting.
Log of register activity when I pressed a key

Code: Select all

check_exception old: 0xffffffff new 0xb
     1: v=0b e=0212 i=0 cpl=0 IP=0008:0000000000100150 pc=0000000000100150 SP=0010:0000000000108040 env->regs[R_EAX]=0000000000000000
RAX=0000000000000000 RBX=0000000000000000 RCX=00000000000000b4 RDX=00000000000003f8
RSI=000000000000000a RDI=00000000000003f8 RBP=0000000000000000 RSP=0000000000108040
R8 =0000000000000000 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=0000000000100150 RFL=00000212 [----A--] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
CS =0008 0000000000000000 00000fff 00a09a00 DPL=0 CS64 [-R-]
SS =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
DS =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
FS =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
GS =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT=     0000000000108160 0000002f
IDT=     00000000001081a0 00000fff
CR0=80000011 CR2=0000000000000000 CR3=0000000000105000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000010 CCD=0000000000107fc8 CCO=EFLAGS  
EFER=0000000000000500
check_exception old: 0xb new 0xd
     2: v=08 e=0000 i=0 cpl=0 IP=0008:0000000000100150 pc=0000000000100150 SP=0010:0000000000108040 env->regs[R_EAX]=0000000000000000
RAX=0000000000000000 RBX=0000000000000000 RCX=00000000000000b4 RDX=00000000000003f8
RSI=000000000000000a RDI=00000000000003f8 RBP=0000000000000000 RSP=0000000000108040
R8 =0000000000000000 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=0000000000100150 RFL=00000212 [----A--] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
CS =0008 0000000000000000 00000fff 00a09a00 DPL=0 CS64 [-R-]
SS =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
DS =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
FS =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
GS =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT=     0000000000108160 0000002f
IDT=     00000000001081a0 00000fff
CR0=80000011 CR2=0000000000000000 CR3=0000000000105000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000010 CCD=0000000000107fc8 CCO=EFLAGS  
EFER=0000000000000500
check_exception old: 0x8 new 0xb

Re: Triple Fault when a key is pressed

Posted: Sat Mar 06, 2021 2:47 am
by nullplan
So the "v=0b" is the vector number, and the "e=0212" is the error code, both in hex. Interrupt 11 is "segment not present". The EXT flag is not set, the IDT flag is, an TI is clear (which is good, for it would be invalid if IDT and TI are set at the same time).

So what does that mean? IDT entry with offset 0x210 was accessed but not present. That is the IDT entry for interrupt 66 or 0x42. Did you map a PIC to base 0x40 and got IRQ 2? That would be weird, since the keyboard is generally on IRQ 1. And IRQ 2 is generally the chaining IRQ. Did you perhaps receive a high IRQ, but initialized the primary PIC such that it did not know IRQ 2 was the chaining IRQ? Or is 0x40 the interrupt base for the secondary IRQ and you got IRQ 10? I don't recall what that one was either.

Re: Triple Fault when a key is pressed

Posted: Sat Mar 06, 2021 4:12 am
by catOS
nullplan wrote:So the "v=0b" is the vector number, and the "e=0212" is the error code, both in hex. Interrupt 11 is "segment not present". The EXT flag is not set, the IDT flag is, an TI is clear (which is good, for it would be invalid if IDT and TI are set at the same time).

So what does that mean? IDT entry with offset 0x210 was accessed but not present. That is the IDT entry for interrupt 66 or 0x42. Did you map a PIC to base 0x40 and got IRQ 2? That would be weird, since the keyboard is generally on IRQ 1. And IRQ 2 is generally the chaining IRQ. Did you perhaps receive a high IRQ, but initialized the primary PIC such that it did not know IRQ 2 was the chaining IRQ? Or is 0x40 the interrupt base for the secondary IRQ and you got IRQ 10? I don't recall what that one was either.
I'm not sure what you mean exactly.

Re: Triple Fault when a key is pressed

Posted: Sat Mar 06, 2021 4:31 am
by Octocontrabass
nullplan wrote:IDT entry with offset 0x210 was accessed but not present. That is the IDT entry for interrupt 66 or 0x42.
IDT entries are twice as big in long mode, and that's reflected in the selector value, so this is the entry for interrupt 0x21. That seems reasonable for a legacy keyboard IRQ.

It would seem Gigasoft's earlier analysis is correct: the IDT entry doesn't have its "present" bit set. Double-check the value you're writing to the "types_attr" field.

Re: Triple Fault when a key is pressed

Posted: Sat Mar 06, 2021 5:37 am
by catOS
Octocontrabass wrote: It would seem Gigasoft's earlier analysis is correct: the IDT entry doesn't have its "present" bit set. Double-check the value you're writing to the "types_attr" field.
What should the present bit be set to?

Re: Triple Fault when a key is pressed

Posted: Sat Mar 06, 2021 6:13 am
by iansjack
A bit can only be 0 or 1.

Re: Triple Fault when a key is pressed

Posted: Sat Mar 06, 2021 9:53 pm
by catOS
I tried your solution but it's still not working

I'm wondering if this is a problem with my GDT

Re: Triple Fault when a key is pressed

Posted: Sun Mar 07, 2021 1:07 am
by Octocontrabass
catOS wrote:I tried your solution but it's still not working
Are you still getting a #NP exception pointing to the IDT entry for interrupt 0x21, or has the error changed?

Re: Triple Fault when a key is pressed

Posted: Sun Mar 07, 2021 1:57 am
by catOS
Octocontrabass wrote: Are you still getting a #NP exception pointing to the IDT entry for interrupt 0x21, or has the error changed?
I think I now have a General Protection Fault caused by a invalid opcode (I'm not sure), here's the log anyway

Code: Select all

check_exception old: 0xffffffff new 0x6
     1: v=06 e=0000 i=0 cpl=0 IP=0008:00000000000001bf pc=00000000000001bf SP=0010:0000000000107f70 env->regs[R_EAX]=0000000000000000
RAX=0000000000000000 RBX=0000000000000000 RCX=00000000000000b4 RDX=00000000000003f8
RSI=000000000000000a RDI=00000000000003f8 RBP=0000000000000000 RSP=0000000000107f70
R8 =0000000000000000 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=00000000000001bf RFL=00000082 [--S----] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
CS =0008 0000000000000000 00000fff 00a09a00 DPL=0 CS64 [-R-]
SS =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
DS =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
FS =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
GS =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT=     0000000000108160 0000002f
IDT=     00000000001081a0 00000fff
CR0=80000011 CR2=0000000000000000 CR3=0000000000105000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000000 CCD=00000000f000ff68 CCO=INCL    
EFER=0000000000000500
check_exception old: 0xffffffff new 0xd
     2: v=0d e=0062 i=0 cpl=0 IP=0008:00000000000001bf pc=00000000000001bf SP=0010:0000000000107f70 env->regs[R_EAX]=0000000000000000
RAX=0000000000000000 RBX=0000000000000000 RCX=00000000000000b4 RDX=00000000000003f8
RSI=000000000000000a RDI=00000000000003f8 RBP=0000000000000000 RSP=0000000000107f70
R8 =0000000000000000 R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=00000000000001bf RFL=00000082 [--S----] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
CS =0008 0000000000000000 00000fff 00a09a00 DPL=0 CS64 [-R-]
SS =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
DS =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
FS =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
GS =0010 0000000000000000 00000fff 00a09300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT=     0000000000108160 0000002f
IDT=     00000000001081a0 00000fff
CR0=80000011 CR2=0000000000000000 CR3=0000000000105000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000000 CCD=00000000f000ff68 CCO=INCL    
EFER=0000000000000500

Re: Triple Fault when a key is pressed

Posted: Sun Mar 07, 2021 7:46 am
by Gigasoft
Well, you don't have an invalid opcode handler, that's why you are getting a GPF.