triple fault when switching to usermode

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
szhou42
Member
Member
Posts: 67
Joined: Thu Apr 28, 2016 12:40 pm
Contact:

triple fault when switching to usermode

Post 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
heat
Member
Member
Posts: 103
Joined: Sat Mar 28, 2015 11:23 am
Libera.chat IRC: heat

Re: triple fault when switching to usermode

Post 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.
If some of you people keep insisting on having backwards compatibitity with the stone age, we'll have stone tools forever.
My Hobby OS: https://github.com/heatd/Onyx
szhou42
Member
Member
Posts: 67
Joined: Thu Apr 28, 2016 12:40 pm
Contact:

Re: triple fault when switching to usermode

Post 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 ?
szhou42
Member
Member
Posts: 67
Joined: Thu Apr 28, 2016 12:40 pm
Contact:

Re: triple fault when switching to usermode

Post 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)
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: triple fault when switching to usermode

Post 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?
heat
Member
Member
Posts: 103
Joined: Sat Mar 28, 2015 11:23 am
Libera.chat IRC: heat

Re: triple fault when switching to usermode

Post 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.
If some of you people keep insisting on having backwards compatibitity with the stone age, we'll have stone tools forever.
My Hobby OS: https://github.com/heatd/Onyx
Post Reply