[freenos] r402 committed - Processes now run unprivileged in ring 3 for x86....

  • From: freenos@xxxxxxxxxxxxxx
  • To: freenos@xxxxxxxxxxxxx
  • Date: Mon, 18 Oct 2010 23:59:46 +0000

Revision: 402
Author: nieklinnenbank
Date: Mon Oct 18 16:51:38 2010
Log: Processes now run unprivileged in ring 3 for x86.
Additionally, arch_context_switch() has been simplified to
only access from and new process_t pointers. The arch
should handle anything neccessary to switch between them.

http://code.google.com/p/freenos/source/detail?r=402

Added:
 /branches/scratch/include/x86/context_switch.h
Modified:
 /branches/scratch/include/kernel/arch.h
 /branches/scratch/system/x86/pc/arch.c

=======================================
--- /dev/null
+++ /branches/scratch/include/x86/context_switch.h      Mon Oct 18 16:51:38 2010
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2010 Niek Linnenbank
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __CONTEXT_SWITCH_H
+#define __CONTEXT_SWITCH_H
+
+#include "types.h"
+
+extern void context_switch(addr_t *old_stack, u8 *old_flags,
+                          addr_t page_dir, addr_t new_stack);
+
+#endif /* __CONTEXT_SWITCH_H */
+
=======================================
--- /branches/scratch/include/kernel/arch.h     Sun Oct 10 16:06:55 2010
+++ /branches/scratch/include/kernel/arch.h     Mon Oct 18 16:51:38 2010
@@ -27,17 +27,14 @@
  */
 size_t arch_total_memory(void);

-/* TODO: could be embedded in the kernel, GRUB module, etc. */
-extern void arch_get_procimage(void);
-
 extern void arch_init_proc(process_t *proc, addr_t entry,
                           addr_t kern_stack, addr_t user_stack);

-extern void arch_context_switch(addr_t *old_stack, u8 *old_flags,
-                               addr_t page_dir, addr_t new_stack);
+extern void arch_context_switch(process_t *old, process_t *new);

 extern void arch_init_clock(void);
 extern void arch_enable_clock(void);
+extern void arch_init_cpu(void);

 #endif /* __ARCH_H */

=======================================
--- /branches/scratch/system/x86/pc/arch.c      Sun Oct 10 16:06:55 2010
+++ /branches/scratch/system/x86/pc/arch.c      Mon Oct 18 16:51:38 2010
@@ -21,11 +21,14 @@
 #include <FreeNOS/cpu.h>
 #include <FreeNOS/smp.h>
 #include <FreeNOS/pit.h>
+#include <FreeNOS/gdt.h>
+#include <FreeNOS/tss.h>
 #include <FreeNOS/io.h>
 #include <FreeNOS/irq.h>
 #include <FreeNOS/printk.h>
 #include <FreeNOS/apic.h>
 #include <FreeNOS/virt_memory.h>
+#include <FreeNOS/context_switch.h>
 #include <string.h>

 static int apic_timer_ic = 0;
@@ -43,23 +46,23 @@
cpu_state_t *regs = (cpu_state_t *) (tmp_stack + STACK_SIZE - sizeof(cpu_state_t));

     /* Point stack. */
-    proc->stack = KERNEL_STACK + STACK_SIZE - sizeof(cpu_state_t);
+    proc->stack = KERN_STACK + STACK_SIZE - sizeof(cpu_state_t);

     /* Clear registers. */
     memset(regs, 0, sizeof(*regs));

     /* Initialize registers. */
     regs->eip  = entry;
-    regs->ss0  = KERNEL_DS_SEL;
-    regs->ss3  = KERNEL_DS_SEL;/*USER_DS_SEL;*/
-    regs->esp0 = KERNEL_STACK + STACK_SIZE;
-    regs->esp3 = KERNEL_STACK + STACK_SIZE;/*user_stack;*/
-    regs->ebp  = KERNEL_STACK + STACK_SIZE;/*user_stack;*/
-    regs->fs   = KERNEL_DS_SEL;/*USER_DS_SEL;*/
-    regs->gs   = KERNEL_DS_SEL;/*USER_DS_SEL;*/
-    regs->es   = KERNEL_DS_SEL;/*USER_DS_SEL;*/
-    regs->ds   = KERNEL_DS_SEL;/*USER_DS_SEL;*/
-    regs->cs   = KERNEL_CS_SEL;
+    regs->ss0  = KERN_DS_SEL;
+    regs->ss3  = USER_DS_SEL;
+    regs->esp0 = KERN_STACK + STACK_SIZE;
+    regs->esp3 = USER_STACK + STACK_SIZE;
+    regs->ebp  = USER_STACK + STACK_SIZE;
+    regs->fs   = USER_DS_SEL;
+    regs->gs   = USER_DS_SEL;
+    regs->es   = USER_DS_SEL;
+    regs->ds   = USER_DS_SEL;
+    regs->cs   = USER_CS_SEL;
     regs->eflags = 0x202;

     /* Release mapping. */
@@ -146,3 +149,21 @@
     arch_init_apic_timer(apic_timer_ic);
 }

+void arch_init_cpu(void)
+{
+    smp_cpu()->flags |= SMP_ACTIVE;
+    gdt_init();
+    tss_init();
+}
+
+void arch_context_switch(process_t *old, process_t *new)
+{
+    /* Update the Task State Segment.. */
+    tss_update(KERN_STACK + STACK_SIZE, KERN_DS_SEL);
+
+    /* Perform Context Switch. */
+    context_switch(old ? &old->stack : NULL,
+                  old ? &old->flags : NULL,
+                  new->page_dir,
+                  new->stack);
+}

Other related posts:

  • » [freenos] r402 committed - Processes now run unprivileged in ring 3 for x86.... - freenos