Triple fault in bochs on the second instruction after sti
Posted: Tue Mar 08, 2016 5:23 pm
The triple fault occurs after I set up the GDT. Relevant portions of code
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
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.
This code occurs in multiple versions of bochs, but doesn't happen in qemu.
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
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
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