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.