[Solved] Exceptions from user mode error

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
User avatar
b.zaar
Member
Member
Posts: 294
Joined: Wed May 21, 2008 4:33 am
Location: Mars MTC +6:00
Contact:

[Solved] Exceptions from user mode error

Post by b.zaar »

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.

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	$
This is the log from CPL = 0 test

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
and this is the test for CPL = 1

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
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.

Code: Select all

	align	0x08
tss_usr	istruc	Tss
at	Tss.esp0,	dd	STACK_TOP
at	Tss.ss0,	dd	FLAT_DD
iend
Edit: Facepalm! I was simply moving the GDT before I had finished setting the bases in the temp table.
"God! Not Unix" - Richard Stallman

Website: venom Dev
OS project: venom OS
Hexadecimal Editor: hexed
Post Reply