Page 1 of 1

Switch to Ring3 task problem

Posted: Sun Jul 23, 2006 4:23 pm
by omin0us
I am trying to switch from ring0 to ring3.
but i am getting a General Protection Fault. on the iret instruction
of my switchTo() function :(
I cant seem to figure out why.

i thought all i needed to do to switch to a ring3 task
was set up the initial stack with

Code: Select all

    *stack = USERDATA32_SEG|0x03;  // SS
    stack--;
    *stack = p->esp;                                 // esp
    stack--;

    *stack = (uint32_t)p;   //push pointer to simulate the stack as if it has been called with switchTo(p);
    stack--;
    
    *stack = 0x0202; // eflags (interrupts enabled)
    stack--;
    *stack = USERCODE32_SEG | 0x03;
    stack--;
    *stack = entry;

    ...

Re:Switch to Ring3 task problem

Posted: Sun Jul 23, 2006 6:41 pm
by Cody

Code: Select all

*stack = (uint32_t)p;  //push pointer to simulate the stack as if it has been called with switchTo(p);
    stack--;
I think the problem may lie in the above code. You cannot insert into some argument in between or iret will not be able to perform his function normally. How about you remove them and have a try again?

Best regards,
Cody

Re:Switch to Ring3 task problem

Posted: Sun Jul 23, 2006 7:41 pm
by omin0us
Cody wrote:
I think the problem may lie in the above code. You cannot insert into some argument in between or iret will not be able to perform his function normally. How about you remove them and have a try again?

Best regards,
Cody
if you read the intel manual for the iret instruction. as well as the section in volume 3 on protection (complete with stack setup diagram)
it says that params passed to the called function will be put in between ss, esp and eflags, cs, eip on the stack

like:

ss
esp
param1
eflags
cs
eip

Re:Switch to Ring3 task problem

Posted: Sun Jul 23, 2006 8:36 pm
by Cody
if you read the intel manual for the iret instruction. as well as the section in volume 3 on protection (complete with stack setup diagram)
it says that params passed to the called function will be put in between ss, esp and eflags, cs, eip on the stack
Well, I am not sure if I understand you well. Here is a simple routine used in early linux, hope this helps.

Code: Select all

#define move_to_user_mode() \
__asm__ ("movl %%esp,%%eax\n\t" \
   "pushl $0x17\n\t" \
   "pushl %%eax\n\t" \
   "pushfl\n\t" \
   "pushl $0x0f\n\t" \
   "pushl $1f\n\t" \
   "iret\n" \
   "1:\tmovl $0x17,%%eax\n\t" \
   "movw %%ax,%%ds\n\t" \
   "movw %%ax,%%es\n\t" \
   "movw %%ax,%%fs\n\t" \
   "movw %%ax,%%gs" \
   :::"ax")
Best regards,
Cody

Re:Switch to Ring3 task problem

Posted: Sun Jul 23, 2006 8:48 pm
by omin0us
you were right. i needed the pointer to the process before everything.
anyway...i got it to switch to the user process now...
but upon executing the first instruction bochs errors with
interrupt() SS selector null

all my first user process does is

void procA()
{
while(1);
}

the asm for that looks like
push ebp <-- this instruction is where bochs stops and says SS selector null
mov ebp, esp
jmp $

Re:Switch to Ring3 task problem

Posted: Mon Jul 24, 2006 8:40 am
by evincarofautumn
You can try removing the prologue/epilogue with [tt]__declspec(naked)[/tt], or, if that doesn't work, with [tt]-fomit-frame-pointer[/tt] (on djgpp). I wouldn't advise using the latter method, though, if you only want one function to be bare.