[Solved] Exceptions from user mode error
Posted: Thu Dec 12, 2013 6:52 pm
Hi, I've been working at this for a few hours but I can't see what I'm missing. I'm writing a small asm 32 bit boot loader. When I test an exception from superviser mode the interrupts work as expected but when testing an exception from user mode Bochs says:
fetch_raw_descriptor: GDT: index (ff57) 1fea > limit (4fff)
I understand it's looking for a GDT entry outside of my GDT table but I don't understand why. The code for both tests is below and the only difference I can tell is the second test is running in ring 3, so I don't know why that changes the GDT index it's looking for.
All my tables are set between 0x1000 and 0x8000. The CPL = 0 stack is at 0x1000 and the CPL = 3 stack is at 0xFF00 so these shouldn't be interfering.
This is the testing code. For a CPL = 3 test I just comment out the first two lines.
This is the log from CPL = 0 test
and this is the test for CPL = 1
You can see it reaches user mode fine and it gets to the exception trigger but it wont go to the exception handler.
This is the minimal TSS I've set, what's not set is left 0.
Edit: Facepalm! I was simply moving the GDT before I had finished setting the bases in the temp table.
fetch_raw_descriptor: GDT: index (ff57) 1fea > limit (4fff)
I understand it's looking for a GDT entry outside of my GDT table but I don't understand why. The code for both tests is below and the only difference I can tell is the second test is running in ring 3, so I don't know why that changes the GDT index it's looking for.
All my tables are set between 0x1000 and 0x8000. The CPL = 0 stack is at 0x1000 and the CPL = 3 stack is at 0xFF00 so these shouldn't be interfering.
This is the testing code. For a CPL = 3 test I just comment out the first two lines.
Code: Select all
mov ax, FLAT_CD
mov ss, ax ; Exception trigger
mov ebx, USER_DD
mov ds, bx
mov es, bx
mov fs, bx
mov gs, bx
push ebx ; ss
mov ebx, 0x0000FF00
push ebx ; esp
mov ebx, 0x0002
push ebx ; eflags
mov ebx, USER_CD
push ebx ; cs
mov ebx, testuser
push ebx ; eip
iret
jmp $
testuser:
mov ax, USER_CD
mov ss, ax ; Exception trigger
jmp $
Code: Select all
00014919114i[BIOS ] Booting from 0000:7c00
00017842689e[CPU0 ] load_seg_reg(SS): not writable data segment
00049600000p[WGUI ] >>PANIC<< POWER button turned off.
00049600000i[CPU0 ] CPU is in protected mode (active)
00049600000i[CPU0 ] CS.mode = 32 bit
00049600000i[CPU0 ] SS.mode = 32 bit
00049600000i[CPU0 ] EFER = 0x00000000
00049600000i[CPU0 ] | EAX=00000008 EBX=00008900 ECX=00000000 EDX=00000000
00049600000i[CPU0 ] | ESP=00000ff0 EBP=00000000 ESI=00008420 EDI=00002000
00049600000i[CPU0 ] | IOPL=0 id vip vif ac vm rf nt of df if tf sf zf af PF cf
00049600000i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00049600000i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 ffffffff 1 1
00049600000i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00049600000i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00049600000i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00049600000i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00049600000i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00049600000i[CPU0 ] | EIP=000083cd (000083cd)
00049600000i[CPU0 ] | CR0=0x60000011 CR2=0x00000000
00049600000i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00049600000i[CPU0 ] 0x00000000000083cd>> jmp .-2 (0x000083cd) : EBFE
Code: Select all
00014919114i[BIOS ] Booting from 0000:7c00
00017842704e[CPU0 ] load_seg_reg(SS): not writable data segment
00017842704e[CPU0 ] fetch_raw_descriptor: GDT: index (ff57) 1fea > limit (4fff)
00017842704e[CPU0 ] fetch_raw_descriptor: GDT: index (ff57) 1fea > limit (4fff)
00017842704i[CPU0 ] CPU is in protected mode (active)
00017842704i[CPU0 ] CS.mode = 32 bit
00017842704i[CPU0 ] SS.mode = 32 bit
00017842704i[CPU0 ] EFER = 0x00000000
00017842704i[CPU0 ] | EAX=00000043 EBX=00008058 ECX=00000000 EDX=00000000
00017842704i[CPU0 ] | ESP=0000ff00 EBP=00000000 ESI=00008420 EDI=00002000
00017842704i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af pf cf
00017842704i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00017842704i[CPU0 ] | CS:0043( 0008| 0| 3) 00000000 ffffffff 1 1
00017842704i[CPU0 ] | DS:004b( 0009| 0| 3) 00000000 ffffffff 1 1
00017842704i[CPU0 ] | SS:004b( 0009| 0| 3) 00000000 ffffffff 1 1
00017842704i[CPU0 ] | ES:004b( 0009| 0| 3) 00000000 ffffffff 1 1
00017842704i[CPU0 ] | FS:004b( 0009| 0| 3) 00000000 ffffffff 1 1
00017842704i[CPU0 ] | GS:004b( 0009| 0| 3) 00000000 ffffffff 1 1
00017842704i[CPU0 ] | EIP=0000805c (0000805c)
00017842704i[CPU0 ] | CR0=0x60000011 CR2=0x00000000
00017842704i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00017842704i[CPU0 ] 0x000000000000805c>> mov ss, ax : 8ED0
00017842704e[CPU0 ] exception(): 3rd (10) exception with no resolution, shutdown status is 00h, resetting
This is the minimal TSS I've set, what's not set is left 0.
Code: Select all
align 0x08
tss_usr istruc Tss
at Tss.esp0, dd STACK_TOP
at Tss.ss0, dd FLAT_DD
iend