Switch to Ring3 task problem

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
omin0us

Switch to Ring3 task problem

Post 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;

    ...
Cody

Re:Switch to Ring3 task problem

Post 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
omin0us

Re:Switch to Ring3 task problem

Post 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
Cody

Re:Switch to Ring3 task problem

Post 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
omin0us

Re:Switch to Ring3 task problem

Post 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 $
evincarofautumn

Re:Switch to Ring3 task problem

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