Getting to Ring 3 x86-64

Discussions on more advanced topics such as monolithic vs micro-kernels, transactional memory models, and paging vs segmentation should go here. Use this forum to expand and improve the wiki!
Post Reply
chicken
Posts: 7
Joined: Fri Aug 09, 2024 4:30 am

Getting to Ring 3 x86-64

Post by chicken »

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 :D
Octocontrabass
Member
Member
Posts: 5543
Joined: Mon Mar 25, 2013 7:01 pm

Re: Getting to Ring 3 x86-64

Post by Octocontrabass »

chicken wrote: Tue Sep 24, 2024 7:05 amMy 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).
In the typical one-kernel-stack-per-thread design, context switching and returning to user mode are two separate steps.
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.
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.

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.
chicken
Posts: 7
Joined: Fri Aug 09, 2024 4:30 am

Re: Getting to Ring 3 x86-64

Post by chicken »

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 #-o . 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 :)
Octocontrabass
Member
Member
Posts: 5543
Joined: Mon Mar 25, 2013 7:01 pm

Re: Getting to Ring 3 x86-64

Post by Octocontrabass »

chicken wrote: Thu Sep 26, 2024 5:26 amCould you elaborate on why combining interrupt handling and context switching is a bad idea and how I should design my kernel instead?
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.)
Post Reply