Page 1 of 1

triple fault when switching to usermode

Posted: Thu Jun 09, 2016 4:46 pm
by szhou42
Hi, I am following JamesM's tutorial.
My problem is, after switched to user mode and temporarily return to the kernel code, it triple faults.

After some debugging I found that it faults on a push instruction. If i try to execute push instruction in gdb, the eip changes to 0xe05b(I believes this behavior is triple fault)
I think it has something to do with user accessing memory belong to kernel, but i am not sure how to fix it

Btw, I didn't do move_stack as the tutorial suggests because I thought it was not necessary(Could this be a problem?).


main.c

Code: Select all

int main(struct multiboot *mboot_ptr, void * initial_stack)
{
    initial_esp = initial_stack;
    init_descriptor_tables();
    init_video();
    timer_install();
    keyboard_install();
    initialise_paging(0x80000000);
    __asm__ __volatile__ ("sti");

    // other stuff

    initialise_syscalls();
    switch_to_user_mode();
    syscall_printf("printing from usermode \n");
    return 0;
}
usermode.asm

Code: Select all

[GLOBAL usermode]
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
    push 0x1B
    push endlabel
    iret
endlabel:
    ret
debugging:

Code: Select all

   0x00100104 <+248>:	call   0x10b6de <switch_to_user_mode>
   0x00100109 <+253>:	sub    $0xc,%esp
=> 0x0010010c <+256>:	push   $0x10d104
   0x00100111 <+261>:	call   0x10b6eb <syscall_printf>
   0x00100116 <+266>:	add    $0x10,%esp
   0x00100119 <+269>:	mov    $0x0,%eax
   0x0010011e <+274>:	mov    -0x4(%ebp),%ecx
   0x00100121 <+277>:	leave
   0x00100122 <+278>:	lea    -0x4(%ecx),%esp
   0x00100125 <+281>:	ret
End of assembler dump.
(gdb) info reg
eax            0x6f0c	28428
ecx            0xf00	3840
edx            0x10d104	1102084
ebx            0x9500	38144
esp            0x6f14	0x6f14
ebp            0x6f28	0x6f28
esi            0x0	0
edi            0x152000	1384448
eip            0x10010c	0x10010c <main+256>
eflags         0x16	[ PF AF ]
cs             0x1b	27
ss             0x23	35
ds             0x23	35
es             0x23	35
fs             0x23	35
gs             0x23	35
(gdb) stepi
0x0000e05b in ?? ()
(gdb) info reg
eax            0x0	0
ecx            0x0	0
edx            0x663	1635
ebx            0x0	0
esp            0x0	0x0
ebp            0x0	0x0
esi            0x0	0
edi            0x0	0
eip            0xe05b	0xe05b
eflags         0x2	[ ]
cs             0xf000	61440
ss             0x0	0
ds             0x0	0
es             0x0	0
fs             0x0	0
gs             0x0	0

Re: triple fault when switching to usermode

Posted: Thu Jun 09, 2016 5:16 pm
by heat
Check the output bochs gives you. And If you don't know how to fix user-mode accessing kernel-mode memory, you should check what you learned while following JamesM's tutorial.
Also, that tutorial has a lot of bugs: http://wiki.osdev.org/James_Molloy%27s_ ... Known_Bugs
Also, If you didn't call move_stack, you probably don't have anywhere to return to (I'm not sure since I didn't follow the tuts).
Lastly, get a register dump of your kernel before executing that push instruction, as it has a lots of good info like the ESP.

Re: triple fault when switching to usermode

Posted: Thu Jun 09, 2016 5:37 pm
by szhou42
TheRussianFail wrote:Check the output bochs gives you. And If you don't know how to fix user-mode accessing kernel-mode memory, you should check what you learned while following JamesM's tutorial.
Also, that tutorial has a lot of bugs: http://wiki.osdev.org/James_Molloy%27s_ ... Known_Bugs
Also, If you didn't call move_stack, you probably don't have anywhere to return to (I'm not sure since I didn't follow the tuts).
Lastly, get a register dump of your kernel before executing that push instruction, as it has a lots of good info like the ESP.
Hi, TheRussianFail
The registers information before/after push instruction is in the post.
It looks fine to me.

The only thing I feel not right is that I am accessing the kernel stack/data in usermode.
Should I allocate some pages for user stack and set esp to point to those pages before changing to usermode ?

Re: triple fault when switching to usermode

Posted: Thu Jun 09, 2016 8:44 pm
by szhou42
I just tried allocate some user-accessible pages to be used as user stack, but after switching to user mode, push instruction still triggers a fault(reading from stack is fine, for example mov eax, (esp) is working good)

Re: triple fault when switching to usermode

Posted: Thu Jun 09, 2016 9:23 pm
by alexfru
szhou42 wrote:I just tried allocate some user-accessible pages to be used as user stack, but after switching to user mode, push instruction still triggers a fault(reading from stack is fine, for example mov eax, (esp) is working good)
What about the user code and data/stack segment descriptors? Are they both 32-bit? What about the user data/stack segment descriptor expansion direction? Expand-up or expand-down?

Re: triple fault when switching to usermode

Posted: Fri Jun 10, 2016 4:50 pm
by heat
szhou42 wrote:I just tried allocate some user-accessible pages to be used as user stack, but after switching to user mode, push instruction still triggers a fault(reading from stack is fine, for example mov eax, (esp) is working good)
I don't think you are allocating stacks well as it has such a low address. I don't know how the series allocates the stack, but I'm not sure it's on a super low address.
Also, check the output

Code: Select all

info tab
gives you in bochs, or

Code: Select all

info mem
and

Code: Select all

info tlb
in qemu.