Sourcer wrote:Hey, this is my first attempt in running a user-mode code.
I followed some tutorials in the web, but still can't figure out why this won't work(32 bit btw)
My GDT is:
[null segment][ring0-data-segment][ring0-code-segment][ring3-data-segment][ring3-code-segment][tss_selector]
Your GDT lay-out is a bit inconvenient when you want to support instructions like SYSENTER/SYSEXIT later on, because those instructions have the following assumptions: KERNEL_DS = KERNEL_CS + 8, USER_CS = KERNEL_CS + 16 and USER_DS = KERNEL_CS + 24.
Furthermore, I think you are approaching this in a weird order anyway. If you get a triple fault, then that is clearly an indication you haven't set up an IDT with more user friendly exception handlers that at least tell you what went wrong together with a dump of the registers. At the very minimum you should use a tool like QEMU and Bochs for this, so that you can at least get an indication of what lead to the triple fault (in case you don't have your own more convenient exception handlers). Besides the exception handlers, you definitely need some kind of system call handler for user mode to be useful.
Sourcer wrote:
Trying to run:
Code: Select all
mov ax, 0x18
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
push (0x18 | 3)
push 4095
pushf
push (0x20 | 3)
push 1
iret
Setting esp to 4095 for the user stack seems to be a bit odd to me. First of all, I would align the address to a 4-byte, 8-byte or even a 16-byte boundary, which means that 0x1000 (= 4096) makes a lot more sense. Furthermore, I wouldn't locate the user stack at 0x0000 - 0x1000, because you don't really want dereferencing NULL-pointers to be a valid operation, which again makes me wonder in what kind of order you are trying to approach things: having a physical and virtual memory manager would really be convenient here.
Sourcer wrote:
Anyway, if i'm already asking, why do i have the OR the GDT segement indices when when loading them to the registers? i haven't done that when i loaded the kernel GDT segements.
The two least significant bits represent the Requested Privilege Level, which should equal to 3 since you want to switch to ring 3.
Do note that I added a few
edits.
Yours sincerely,
Stephan.