Browse Source

ring3 switch code in user.S now

Dale Weiler 7 years ago
parent
commit
31900155fb
4 changed files with 59 additions and 25 deletions
  1. 5 1
      kernel/include/system.h
  2. 4 21
      kernel/sys/task.c
  3. 5 3
      kernel/task.S
  4. 45 0
      kernel/user.S

+ 5 - 1
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;

+ 4 - 21
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);
 }
 
 /*

+ 5 - 3
kernel/task.S

@@ -1,12 +1,14 @@
 .section .text
 .align 4
 
-.global copy_page_physical
-.type copy_page_physical, @function
-
+/* Disable paging mask */
 .set dp, 0x7FFFFFFF
+/* Enable paging mask */
 .set ep, 0x80000000
 
+.global copy_page_physical
+.type copy_page_physical, @function
+
 copy_page_physical:
     /* Preserve contents of EBX */
     push %ebx

+ 45 - 0
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