Page 1 of 1

[Solved]User Mode (Ring 3)

Posted: Tue Jul 19, 2011 8:45 am
by melgmry0101b
Hi everyone :D ,
I want to know how can i switch to user mode.
I have the task state segment (TSS) but i don't know how to switch to user mode.
I have followed the tutorial that provided in the wiki about setting up the user mode but it didn't run because i am using MSVC 2005 inline assembly not gcc or other compilers like it.
Now i have a question:
How can i switch to user mode?

----------------------------------------------
Thanks in advance :)

Re: User Mode (Ring 3)

Posted: Tue Jul 19, 2011 10:17 am
by egos
1. Try this:

Code: Select all

  push USERDATA_SELECTOR ; (RPL=3)
  push stackpointer
  push flags
  push USERCODE_SELECTOR ; (RPL=3)
  push startaddress
  iret
Or this:

Code: Select all

  push USERDATA_SELECTOR ; (RPL=3)
  push stackpointer
  push USERCODE_SELECTOR ; (RPL=3)
  push startaddress
  retf
3. Use far call/int to call/int gate.

Re: User Mode (Ring 3)

Posted: Tue Jul 19, 2011 3:17 pm
by Combuster
How did reading the manuals, tutorials, and existing forum posts not answer your question?

Re: User Mode (Ring 3)

Posted: Wed Jul 20, 2011 8:27 pm
by Nessphoro

Re: User Mode (Ring 3)

Posted: Thu Jul 21, 2011 2:59 am
by melgmry0101b
egos wrote:1. Try this:

Code: Select all

  push USERDATA_SELECTOR ; (RPL=3)
  push stackpointer
  push flags
  push USERCODE_SELECTOR ; (RPL=3)
  push startaddress
  iret
Or this:

Code: Select all

  push USERDATA_SELECTOR ; (RPL=3)
  push stackpointer
  push USERCODE_SELECTOR ; (RPL=3)
  push startaddress
  retf
3. Use far call/int to call/int gate.
Thank you very much
Combuster wrote:How did reading the manuals, tutorials, and existing forum posts not answer your question?
I have read as much as i can , but i didn't find a solution.
Thank you i used it before and i think i will give it another try but in another way.

Re: User Mode (Ring 3)

Posted: Thu Jul 21, 2011 11:57 am
by Nessphoro
By the way reading from floppy via BIOS interrupt is a bad idea

Re: User Mode (Ring 3)

Posted: Thu Jul 21, 2011 1:04 pm
by melgmry0101b
Nessphoro wrote:By the way reading from floppy via BIOS interrupt is a bad idea
My FDC is worse than BIOS ints because it case a bad sectors in the floppy on some machines.

Re: User Mode (Ring 3)

Posted: Fri Jul 22, 2011 10:02 am
by melgmry0101b
Hi, :D
I am using this code to enter user mode but it always case General Protection Fault (#GPF):

Code: Select all

	
_asm {

		cli
		mov ax, 0x23   ; user mode data selector is 0x20 (GDT entry 3). Also sets RPL to 3
		mov ds, ax
		mov es, ax
		mov fs, ax
		mov gs, ax

		push 0x23	       ; SS, notice it uses same selector as above
		push esp	       ; ESP
		pushfd	       ; EFLAGS

		pop eax
		or eax, 0x200     ; enable IF in EFLAGS
		push eax

		push 0x1b	        ; CS, user mode code selector is 0x18. With RPL 3 this is 0x1b
		lea eax, [a]	        ; EIP first
		push eax
		iretd
	a:
		add esp, 4           ;fix stack
	}
And Bochs Debugger gave me this error:
[CPU0] check_cs <0x0023> : not a valid code segment !
Can anyone help me?
----------------------------------
Thanks in advance. :D

Re: User Mode (Ring 3)

Posted: Fri Jul 22, 2011 12:16 pm
by Nessphoro
Yes - that's a data segment - you need a valid code segment from the GDT

0x1B - If properly set up I believe

Just follow the tutorial man - it even avoids that ugly stack fix

Re: User Mode (Ring 3)

Posted: Sat Jul 23, 2011 5:17 pm
by melgmry0101b
Hi everyone,

Code: Select all

	asm volatile(" \
				 cli; \
				 mov $0x23, %ax; \
				 mov %ax, %ds; \
				 mov %ax, %es; \
				 mov %ax, %fs; \
				 mov %ax, %gs; \
				 \ 
				 mov %esp, %eax; \ 
				 pushl $0x23; \ 
		    	 pushl %eax; \ 
				 pushf; \ 
				 mov $0x200, %eax; \ 
				 push %eax; \ 
				 pushl $0x1B; \ 
				 push $1f; \ 
				 iret; \ 
				 1: \ 
				 ");
This code is the code that provided with the tutorial of user mode but it is in AT&T syntax and Microsoft Visual C++ is using Intel syntax and i didn't use AT&T before so that can anyone help me by converting it to Intel syntax?
------------------------------------------------
Thanks in advance.

Re: User Mode (Ring 3)

Posted: Sat Jul 23, 2011 6:54 pm
by Jezze
Taken directly from my os. I use this C header to call the code:

Code: Select all

extern void cpu_usermode(unsigned int address);
The address parameter is the address of where you want the code to start executing after you have entered usermode. I just find it more robust than using the jump forward.

Code: Select all

global cpu_usermode
cpu_usermode:
    cli
    mov ax, 0x23
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov eax, esp
    push 0x23
    push eax
    pushf
    pop eax
    or eax, 0x200
    push eax
    push 0x1B
    mov eax, [esp + 20]
    push eax
    iret

Re: User Mode (Ring 3)

Posted: Sun Jul 24, 2011 12:47 pm
by melgmry0101b
Thank you very much Jezze. :D