Triple fault in bochs on the second instruction after sti

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
Pyrofan1
Member
Member
Posts: 234
Joined: Sun Apr 29, 2007 1:13 am

Triple fault in bochs on the second instruction after sti

Post by Pyrofan1 »

The triple fault occurs after I set up the GDT. Relevant portions of code

Code: Select all

asm volatile("cli");
    asm volatile("lgdt %0" : : "m"(location));
    loadSegments();
    BOCHS_BREAK();
    asm volatile("sti");
    /*/asm volatile("mov $0xFFFFFFFF, %%eax\n\t"
                 "mov $0xFFFFFFFF, %%ebx\n\t" : : :"ebx", "eax");*/ //triple fault happens on this instruction
    asm volatile("nop\n\t"
                 "nop\n\t" //or this one if the above code is commented out
                 "nop\n\t"
                 "nop\n\t");

Code: Select all

loadSegments:
    ljmp $0x08, $loadcs
loadcs:
    mov $0x10, %ax
    mov %ax, %ds
    mov %ax, %ss
    mov %ax, %fs
    mov %ax, %gs
    mov %ax, %es

    ret
I've set up the gdt with a 32 bit code and data segment as well as a 64 bit code and data segment to be used later. The gdt is successfully loaded and bochs confirms this

Code: Select all

GDT[0x00]=??? descriptor hi=0x00000000, lo=0x00000000
GDT[0x01]=Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Non-Conforming, Accessed, 32-bit
GDT[0x02]=Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
GDT[0x03]=Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Non-Conforming, 64-bit
GDT[0x04]=Data segment, base=0x00000000, limit=0xffffffff, Read/Write
After experimenting a little, I've found that the triple fault happens on the second instruction after the sti instruction. I've tested it with several instructions ret (where I first noticed it), add, push and nop. It also happens at a different memory address when the instructions are different sizes. For example with nops, the fault happens at 0x100850, while with add it happens at 0x100855. It's particularly puzzling because an exception should only occur with nop when used with the lock prefix. Bochs shows that a GPF is the exception that happens, but I'm not sure how a nop could generate a GPF when my segments are set up correctly.

Code: Select all

00185622638e[CPU0  ] interrupt(): vector must be within IDT table limits, IDT.limit = 0x0
00185622638e[CPU0  ] interrupt(): vector must be within IDT table limits, IDT.limit = 0x0
00185622638e[CPU0  ] interrupt(): vector must be within IDT table limits, IDT.limit = 0x0
00185622638i[CPU0  ] CPU is in protected mode (active)
00185622638i[CPU0  ] CS.mode = 32 bit
00185622638i[CPU0  ] SS.mode = 32 bit
00185622638i[CPU0  ] EFER   = 0x00000000
00185622638i[CPU0  ] | EAX=00000010  EBX=00010000  ECX=00000028  EDX=ffffffff
00185622638i[CPU0  ] | ESP=0010c3bc  EBP=0010c400  ESI=00000000  EDI=00000000
00185622638i[CPU0  ] | IOPL=0 id vip vif ac vm RF nt of df IF tf sf ZF af PF cf
00185622638i[CPU0  ] | SEG sltr(index|ti|rpl)     base    limit G D
00185622638i[CPU0  ] |  CS:0008( 0001| 0|  0) 00000000 ffffffff 1 1
00185622638i[CPU0  ] |  DS:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00185622638i[CPU0  ] |  SS:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00185622638i[CPU0  ] |  ES:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00185622638i[CPU0  ] |  FS:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00185622638i[CPU0  ] |  GS:0010( 0002| 0|  0) 00000000 ffffffff 1 1
00185622638i[CPU0  ] | EIP=00100850 (00100850)
00185622638i[CPU0  ] | CR0=0x60000011 CR2=0x00000000
00185622638i[CPU0  ] | CR3=0x00000000 CR4=0x00000000
00185622638e[CPU0  ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
This code occurs in multiple versions of bochs, but doesn't happen in qemu.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Triple fault in bochs on the second instruction after st

Post by Brendan »

Hi,
Pyrofan1 wrote:

Code: Select all

00185622638e[CPU0  ] interrupt(): vector must be within IDT table limits, IDT.limit = 0x0

Code: Select all

00185622638i[CPU0  ] | IOPL=0 id vip vif ac vm RF nt of df IF tf sf ZF af PF cf
An IRQ occurred (because your "STI" enabled IRQs) causing the CPU to try to start an interrupt handler; but your IDT is not valid (IDT limit is zero) so CPU can't start the interrupt handler and generates an exception instead (which causes another exception which causes double fault which causes triple fault, because the IDT is not valid for any interrupt).


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Pyrofan1
Member
Member
Posts: 234
Joined: Sun Apr 29, 2007 1:13 am

Re: Triple fault in bochs on the second instruction after st

Post by Pyrofan1 »

It seems like I'm getting interrupts from the PIT on interrupt #8 because I haven't remapped the PIC. The thing is that I'm planning on using the APIC so I disabled the PIC like so.

Code: Select all

//acknowledge any current IRQs
    outportb(0xA0, 0x20);
    outportb(0x20, 0x20);
//disable the PIC
    outportb(0xA1, 0xFF);
    outportb(0x21, 0xFF);
But it doesn't seem to be working
FallenAvatar
Member
Member
Posts: 283
Joined: Mon Jan 03, 2011 6:58 pm

Re: Triple fault in bochs on the second instruction after st

Post by FallenAvatar »

Since you haven't setup an IDT, why are you enabling interrupts? Either don't enable interrupts, or setup an IDT.

- Monk
Pyrofan1
Member
Member
Posts: 234
Joined: Sun Apr 29, 2007 1:13 am

Re: Triple fault in bochs on the second instruction after st

Post by Pyrofan1 »

I do have an IDT setup at this point.
FallenAvatar
Member
Member
Posts: 283
Joined: Mon Jan 03, 2011 6:58 pm

Re: Triple fault in bochs on the second instruction after st

Post by FallenAvatar »

00185622638e[CPU0 ] interrupt(): vector must be within IDT table limits, IDT.limit = 0x0
Bochs says you are lying.

- Monk
Pyrofan1
Member
Member
Posts: 234
Joined: Sun Apr 29, 2007 1:13 am

Re: Triple fault in bochs on the second instruction after st

Post by Pyrofan1 »

I fixed the issue in my original post. My current issue is that I'm still getting interrupts from the PIT even though I have disabled the PIC.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Triple fault in bochs on the second instruction after st

Post by Combuster »

I still see no IDT. I still see no code to mask all PIC interrupts.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Pyrofan1
Member
Member
Posts: 234
Joined: Sun Apr 29, 2007 1:13 am

Re: Triple fault in bochs on the second instruction after st

Post by Pyrofan1 »

Here is a dump of my IDT, though I'm not sure how it's relevant. All the non-listed entries are marked as not present.

Code: Select all

Interrupt Descriptor Table (base=0x0000000000103040, limit=2048):
IDT[0x00]=32-Bit Interrupt Gate target=0x0008:0x0010084e, DPL=0
IDT[0x01]=32-Bit Interrupt Gate target=0x0008:0x00100854, DPL=0
IDT[0x02]=32-Bit Interrupt Gate target=0x0008:0x0010085a, DPL=0
IDT[0x03]=32-Bit Interrupt Gate target=0x0008:0x00100860, DPL=0
IDT[0x04]=32-Bit Interrupt Gate target=0x0008:0x00100866, DPL=0
IDT[0x05]=32-Bit Interrupt Gate target=0x0008:0x0010086c, DPL=0
IDT[0x06]=32-Bit Interrupt Gate target=0x0008:0x00100872, DPL=0
IDT[0x07]=32-Bit Interrupt Gate target=0x0008:0x00100878, DPL=0
IDT[0x08]=32-Bit Interrupt Gate target=0x0008:0x0010087e, DPL=0
IDT[0x09]=32-Bit Interrupt Gate target=0x0008:0x00100882, DPL=0
IDT[0x0a]=32-Bit Interrupt Gate target=0x0008:0x00100888, DPL=0
IDT[0x0b]=32-Bit Interrupt Gate target=0x0008:0x0010088c, DPL=0
IDT[0x0c]=32-Bit Interrupt Gate target=0x0008:0x00100890, DPL=0
IDT[0x0d]=32-Bit Interrupt Gate target=0x0008:0x00100894, DPL=0
IDT[0x0e]=32-Bit Interrupt Gate target=0x0008:0x00100898, DPL=0
IDT[0x0f]=32-Bit Interrupt Gate target=0x0008:0x0010089c, DPL=0
IDT[0x10]=32-Bit Interrupt Gate target=0x0008:0x001008a2, DPL=0
IDT[0x11]=32-Bit Interrupt Gate target=0x0008:0x001008a8, DPL=0
IDT[0x12]=32-Bit Interrupt Gate target=0x0008:0x001008ac, DPL=0
IDT[0x13]=32-Bit Interrupt Gate target=0x0008:0x001008b2, DPL=0
IDT[0x14]=32-Bit Interrupt Gate target=0x0008:0x001008b8, DPL=0
IDT[0x15]=32-Bit Interrupt Gate target=0x0008:0x001008be, DPL=0
IDT[0x16]=32-Bit Interrupt Gate target=0x0008:0x001008be, DPL=0
IDT[0x17]=32-Bit Interrupt Gate target=0x0008:0x001008be, DPL=0
IDT[0x18]=32-Bit Interrupt Gate target=0x0008:0x001008be, DPL=0
IDT[0x19]=32-Bit Interrupt Gate target=0x0008:0x001008be, DPL=0
IDT[0x1a]=32-Bit Interrupt Gate target=0x0008:0x001008be, DPL=0
IDT[0x1b]=32-Bit Interrupt Gate target=0x0008:0x001008be, DPL=0
IDT[0x1c]=32-Bit Interrupt Gate target=0x0008:0x001008be, DPL=0
IDT[0x1d]=32-Bit Interrupt Gate target=0x0008:0x001008be, DPL=0
IDT[0x1e]=32-Bit Interrupt Gate target=0x0008:0x001008be, DPL=0
IDT[0x1f]=32-Bit Interrupt Gate target=0x0008:0x001008be, DPL=0
Combuster wrote:I still see no code to mask all PIC interrupts.
Pyrofan1 wrote:It seems like I'm getting interrupts from the PIT on interrupt #8 because I haven't remapped the PIC. The thing is that I'm planning on using the APIC so I disabled the PIC like so.

Code: Select all

//acknowledge any current IRQs
    outportb(0xA0, 0x20);
    outportb(0x20, 0x20);
//disable the PIC
    outportb(0xA1, 0xFF);
    outportb(0x21, 0xFF);
But it doesn't seem to be working
User avatar
BrightLight
Member
Member
Posts: 901
Joined: Sat Dec 27, 2014 9:11 am
Location: Maadi, Cairo, Egypt
Contact:

Re: Triple fault in bochs on the second instruction after st

Post by BrightLight »

At least in my Bochs, I needed a short delay after I disabled the PIC before it stopped sending interrupts. I waited for IRQs to happen during this short delay, but seeing as your IDT is not working...
If you have a 16-bit stub, it would work...
You know your OS is advanced when you stop using the Intel programming guide as a reference.
Pyrofan1
Member
Member
Posts: 234
Joined: Sun Apr 29, 2007 1:13 am

Re: Triple fault in bochs on the second instruction after st

Post by Pyrofan1 »

At least in my Bochs, I needed a short delay after I disabled the PIC before it stopped sending interrupts.
I was not aware of that. I ending up remapping the PIC and filling the rest of the IDT with handlers that only acknowledge the IRQ before disabling the PIC. This works out perfectly, especially since I only need the IDT to handle exceptions before I enter long mode and setup a 64 bit IDT.
Post Reply