Triple Fault when a key is pressed
Triple Fault when a key is pressed
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.
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
You forgot to set the Present bit in your IDT entries.
-
- Member
- Posts: 5568
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Triple Fault when a key is pressed
Which virtual machine are you using? Most of them have built-in debugging tools that can tell you more about the fault.catOS wrote:I can't provide much debugging details
Re: Triple Fault when a key is pressed
qemu. I tried debugging with gdb but unfortunately I'm not getting very good results.Octocontrabass wrote: Which virtual machine are you using? Most of them have built-in debugging tools that can tell you more about the fault.
-
- Member
- Posts: 5568
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Triple Fault when a key is pressed
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.
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
Log of register activity when I pressed a keyOctocontrabass 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.
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
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.
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.
Carpe diem!
Re: Triple Fault when a key is pressed
I'm not sure what you mean exactly.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.
-
- Member
- Posts: 5568
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Triple Fault when a key is pressed
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.nullplan wrote:IDT entry with offset 0x210 was accessed but not present. That is the IDT entry for interrupt 66 or 0x42.
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
What should the present bit be set to?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.
Re: Triple Fault when a key is pressed
A bit can only be 0 or 1.
Re: Triple Fault when a key is pressed
I tried your solution but it's still not working
I'm wondering if this is a problem with my GDT
I'm wondering if this is a problem with my GDT
-
- Member
- Posts: 5568
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Triple Fault when a key is pressed
Are you still getting a #NP exception pointing to the IDT entry for interrupt 0x21, or has the error changed?catOS wrote:I tried your solution but it's still not working
Re: Triple Fault when a key is pressed
I think I now have a General Protection Fault caused by a invalid opcode (I'm not sure), here's the log anywayOctocontrabass wrote: Are you still getting a #NP exception pointing to the IDT entry for interrupt 0x21, or has the error changed?
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
Well, you don't have an invalid opcode handler, that's why you are getting a GPF.