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.
After having implemented multitasking, I added the switch to the user mode (I confirmed that I cannot access pages only accessible to kernel mode)
My challenge is now to access system calls from the user mode. No matter what way I try I get a General Protection Fault.
I tried to setup interrupt 0x80 using the same mechanism I use to handle Page Faults or IRQs (and which works fine), but I get a GPF when I try to raise int 0x80.
I tried to use SYSENTER, but just trying to call wrmsr leads to a GPF (note: I'm in 32-bit):
Hi, make sure to set the DPL of the IDT entry for your sw int to 3 so that it is accessible from user land.
Also, I think you should be writing your ring 0 code selector to MSR 0x174. A code selector of 0x9a has a privilege level of 2. HINT: Most people have a ring 0 code selector of 0x8. IIRC, you also need your ring 0 data selector to be the next entry in the GDT.
If a trainstation is where trains stop, what is a workstation ?
Regarding the interruptions, indeed I did not set ring 3 in the DPL. This is fixed, but I still get a GPF. Interestingly, I get a GPF even when I stay in kernel mode, even though keyboard/mouse interrupt handling works fine. So there's something I'm doing wrong with my interruptions.
I tried changing the MSR parameter 0x174 code selector to 0x8 but still get the GPF as well. I set my GDT entries as:
- null segment
- kernel code segment
- kernel data segment
- user mode code segment
- user mode data segment
Regarding the interruptions, indeed I did not set ring 3 in the DPL. This is fixed, but I still get a GPF. Interestingly, I get a GPF even when I stay in kernel mode, even though keyboard/mouse interrupt handling works fine. So there's something I'm doing wrong with my interruptions.
I tried changing the MSR parameter 0x174 code selector to 0x8 but still get the GPF as well. I set my GDT entries as:
- null segment
- kernel code segment
- kernel data segment
- user mode code segment
- user mode data segment
I am using 64 bit mode, my GDT looks like this, the User CS and SS are in a different order. See 24594_APM_v3.pdf, lookup sysret.
You seem to be using an AMD CPU. For the Intel processor and SYSENTER, it looks like ring 0 code / ring 0 data / ring 3 code / ring 3 data is the right order (http://wiki.osdev.org/Sysenter)
Also, I finally found what I did wrong in my interruption code (I forgot a step to catch interrupt 0x80). It would still be nice to be able to use SYSENTER / SYSEXIT though, but my next is anyway to create a wrapper that hides how the system call is made.
lpoulain wrote:You seem to be using an AMD CPU. For the Intel processor and SYSENTER, it looks like ring 0 code / ring 0 data / ring 3 code / ring 3 data is the right order (http://wiki.osdev.org/Sysenter)
Oops, sorry about that. I am using SYSCALL and just read yours as SYSCALL not as you typed it.