diff --git a/kernel/include/system.h b/kernel/include/system.h index d42f6520..0bbd1d5e 100644 --- a/kernel/include/system.h +++ b/kernel/include/system.h @@ -85,7 +85,11 @@ extern void set_kernel_stack(uintptr_t stack); extern void idt_install(void); extern void idt_set_gate(unsigned char num, void (*base)(void), unsigned short sel, unsigned char flags); -/* Registers */ +/* Registers + * + * Note: if the order of these changes, sys/task.S must be changed to use + * the correct offsets as well. + */ struct regs { unsigned int gs, fs, es, ds; unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; diff --git a/kernel/sys/task.c b/kernel/sys/task.c index 4c4a4bc1..0390a8bf 100644 --- a/kernel/sys/task.c +++ b/kernel/sys/task.c @@ -26,7 +26,7 @@ page_directory_t *current_directory; /* * Clone a page directory and its contents. * (If you do not intend to clone the contents, do it yourself!) - * + * * @param src Pointer to source directory to clone from. * @return A pointer to a new directory. */ @@ -485,6 +485,8 @@ void switch_next(void) { } +extern void enter_userspace(uintptr_t location, uintptr_t stack); + /* * Enter ring 3 and jump to `location`. * @@ -500,26 +502,7 @@ enter_user_jmp(uintptr_t location, int argc, char ** argv, uintptr_t stack) { PUSH(stack, uintptr_t, (uintptr_t)argv); PUSH(stack, int, argc); - - asm volatile( - "mov %1, %%esp\n" - "pushl $0xDECADE21\n" /* Magic */ - "mov $0x23, %%ax\n" /* Segment selector */ - "mov %%ax, %%ds\n" - "mov %%ax, %%es\n" - "mov %%ax, %%fs\n" - "mov %%ax, %%gs\n" - "mov %%esp, %%eax\n" /* Stack -> EAX */ - "pushl $0x23\n" /* Segment selector again */ - "pushl %%eax\n" - "pushf\n" /* Push flags */ - "popl %%eax\n" /* Fix the Interrupt flag */ - "orl $0x200, %%eax\n" - "pushl %%eax\n" - "pushl $0x1B\n" - "pushl %0\n" /* Push the entry point */ - "iret\n" - : : "m"(location), "r"(stack) : "%ax", "%esp", "%eax"); + enter_userspace(location, stack); } /* diff --git a/kernel/task.S b/kernel/task.S index b7206699..c193a236 100644 --- a/kernel/task.S +++ b/kernel/task.S @@ -1,12 +1,14 @@ .section .text .align 4 +/* Disable paging mask */ +.set dp, 0x7FFFFFFF +/* Enable paging mask */ +.set ep, 0x80000000 + .global copy_page_physical .type copy_page_physical, @function -.set dp, 0x7FFFFFFF -.set ep, 0x80000000 - copy_page_physical: /* Preserve contents of EBX */ push %ebx diff --git a/kernel/user.S b/kernel/user.S index 1f131560..c0ebf2a2 100644 --- a/kernel/user.S +++ b/kernel/user.S @@ -19,3 +19,48 @@ return_to_userspace: read_eip: mov (%esp), %eax ret + +/* Enter userspace (ring3) */ +.global enter_userspace +.type enter_userspace, @function + +.set MAGIC, 0xDECADE21 + +enter_userspace: + pushl %ebp + mov %esp, %ebp + mov 0xC(%ebp), %edx + mov %edx, %esp + pushl $MAGIC + + /* Segement selector */ + mov $0x23,%ax + + /* Save segement registers */ + mov %eax, %ds + mov %eax, %es + mov %eax, %fs + mov %eax, %gs + + /* Stack */ + mov %esp, %eax + + /* Segmenet selector */ + pushl $0x23 + pushl %eax + + /* Push flags and fix interrupt flag */ + pushf + popl %eax + + /* Request ring3 */ + orl $0x200, %eax + pushl %eax + pushl $0x1B + + /* Push entry point */ + pushl 0x8(%ebp) + + iret + popl %ebp + ret