Page 1 of 1

GPF when moving to usermode.

Posted: Mon Apr 13, 2009 1:36 pm
by eXeCuTeR
Sooo, I'm trying to get to usermode and it surprisingly it doesn't work.
Actually I'm getting a general protection fault, but I also have made a couple of changes which made bochs restart (can't remember what the changes were but they were really tiny and I was still wondering why my code wasn't working properly)

Here's my code:

Code: Select all

global switchto_usermode
switchto_usermode:
; when an interrupt is called, 5 things are pushed:
; eip, cs, eflags, esp, ss
; stack grows downwards so i'll push these on the backwards order
	cli
	mov ax, 0x23 ; 0x23 == 0x20 (user mode data segment) | 0x03 (RPL = ring 3)
	mov ds, ax
	mov fs, ax
	mov gs, ax
	mov es, ax
	
	mov eax, esp
	push 0x23 ; ss
	push eax ; esp
	push 0x202
	;pushf ; push the eflags
	;pop eax
	;or eax, 0x200 ; OR the 9th bit (IF, interrupt flag, bit) == sti
	;push eax ; push the eflags again
	push 0x1B ; 0x18 (usermode code segment) | 0x03
	push flush
	iret
flush:
gdt.c:

Code: Select all

code code code...

void initialize_gdt(void)
{
	unsigned int i = 1, limit[NUM_ENTRIES], base[NUM_ENTRIES];
	unsigned char  granularity[NUM_ENTRIES];
	
	limit[0] = base[0] = access[0] = granularity[0] = 0x0; // null segment
	for(;i<NUM_ENTRIES; i++)
	{
		limit[i] = 0xFFFFFFFF;
		base[i] = 0x0;
	}
	
	unsigned char access[NUM_ENTRIES] = { 0x0, 0x9A, 0x92, 0xFA, 0xF2, 0xE9 };
		
	for(i=1;i<NUM_ENTRIES;i++)
		granularity[i] = 0xCF;
	
	/* initializing tss */	
	memset(&tss, 0, sizeof(s_tss));
	
	tss.ss0 = 0x10;
	tss.esp0 = 0x0;
	tss.cs   = 0x1B/*0x18|0x3*/;
	tss.ss = tss.ds = tss.es = tss.fs = tss.gs = 0x23/*0x20|0x3*/;
	
	base[NUM_ENTRIES-1] = (unsigned int)&tss;
	limit[NUM_ENTRIES-1] = (unsigned int)(sizeof(s_tss) + base[NUM_ENTRIES-1]);
	granularity[NUM_ENTRIES-1] = 0x0;
	
	build_gdt((unsigned int *)base, (unsigned int *)limit, (unsigned char *)access, (unsigned char *)granularity);
	
	gdt_install((unsigned int)&gdt.gdt_ptr);
	tss_install();
}
I'm calling switchto_usermode from my main.c file of course.

Please help me, I'm desperate.
Thanks in advance.

Re: GPF when moving to usermode.

Posted: Mon Apr 13, 2009 2:00 pm
by earlz
Try changing eflags to 0x02 rather than 0x202.. this will make it so interrupts are disabled. You must have a TSS before interrupts will work(or syscalls) --as in, read further into the tutorial

Re: GPF when moving to usermode.

Posted: Mon Apr 13, 2009 2:58 pm
by eXeCuTeR
Yay, managed to get it working.