So I am currently working on my hobby-os kernel written in Rust. I previously set up multitaksing (which itself needs to be improved but that is a topic for another post), now I want to test creating usermode processes and so far, have compelted the following steps.
- Set up a GDT with userspace entries and a TSS
- Mapped the new user "program" (a function with a loop) and it's stack to userspace.
- Set up Multitaksing & Interrupt Handling for Ring 0
What I am wondering is what steps are necessary when switching to Ring 3. My kernel tripple faults if I attempt to switch to the newly created usermode process' cpu context (iretq frame with usermode CS, SS, newly mapped stack and function entry).
I followed the following book quite closely when it comes to the implementation details. https://github.com/dreamportdev/Osdev-Notes.
This is my github repository, feel free to check out the userspace branch, which is my current attempt at "fixing the issue". I added a loop in the TaskScheduler::switch_process function so that it does not tripple fault while testing, but the issue still presists if I remove the loop. https://github.com/chickensoftware/os/tree/userspace
Thanks in advance
Getting to Ring 3 x86-64
-
- Member
- Posts: 5449
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Getting to Ring 3 x86-64
In the typical one-kernel-stack-per-thread design, context switching and returning to user mode are two separate steps.
Ah. This tutorial incorrectly combines interrupt handling and context switching. Most osdev tutorials are written by beginners, and beginners tend to make beginner mistakes that aren't obvious unless you know better.chicken wrote: ↑Tue Sep 24, 2024 7:05 amI followed the following book quite closely when it comes to the implementation details. https://github.com/dreamportdev/Osdev-Notes.
If you still want to debug your code even though you'll have to rewrite it to fix the tutorial's mistakes, share your QEMU interrupt log. That'll help us find the problems that lead to the triple fault.
Re: Getting to Ring 3 x86-64
I am currently debugging the code and already had to change somethings. At first, I couldn't get any debug output at all bc I had enabled kvm when launching qemu . Could you elaborate on why combining interrupt handling and context switching is a bad idea and how I should design my kernel instead?
Thanks again
Thanks again
-
- Member
- Posts: 5449
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Getting to Ring 3 x86-64
It's a bad idea because it makes things much more difficult than you might expect. It's mostly small things, like how interrupts that occur in ring 0 don't switch stacks, or how you need to send EOI for hardware interrupts but can't send EOI for software interrupts. I'm pretty sure you can work around these problems, but it's not worth the effort.
The wiki has a pretty good guide for how context switching is usually done. (Although I personally would reduce the assembly code to only stack switching and do the TCB and CR3 stuff right before calling the assembly function.)