octacone wrote:
I have no idea what is going on. I checked everything twice. I just don't get it. Other people have entered user mode without any problem, every tutorial I've ever seen just magically works.
I understand the feeling. Took me about 5 days of banging my head on the wall to get it working. And it was because I wasn't using a separate user-access paged stack.
Code:
enter_usermode:
;push ebp
mov ebp, esp
cli
mov ax, 0x20 | 3
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
push 0x20 | 3 ; push ss3
mov ecx, [ebp+8]
push ecx ; push esp3
pushf ; push flags onto stack
pop eax ; pop into eax
or eax, 0x200 ; set IF (enable interrupts)
push eax ; push eflags
push 0x18 | 3 ; push CS, requested priv. level = 3
xor eax, eax ; Clear eax
mov eax, [ebp+4] ; Load new IP into eax
push eax ; Push EIP onto stack
iret
To use this, allocate a new physical page for the user-level stack. Map that physical page to some address and make sure that you set the user-accessible flag in the page table entry. enter_usermode(address_of_function, user_stack). Remember that the stack grows down, so if for instance, you chose to map 0x0-0x1000 for your user stack, pass the function 0xF00 as a test.
I have never heard of this concept before. I am still getting triple faults. What am I doing wrong?
Bochs log: (unk. ctxt): mov eax, dword ptr ds:0xcf1f0013 ; a113001fcf