aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/user/process.c
diff options
context:
space:
mode:
authorAlex Auvolat <alex.auvolat@ens.fr>2015-02-13 18:53:36 +0100
committerAlex Auvolat <alex.auvolat@ens.fr>2015-02-13 18:53:36 +0100
commit0ea68568372b7b7b20bca6985ae4b36e8c99c0e9 (patch)
tree832f7f4ac8e2537cf5aee531634d01499bb4a318 /src/kernel/user/process.c
parent7aafc22a01de5cabb99aed76782f6c0999b7de05 (diff)
downloadkogata-0ea68568372b7b7b20bca6985ae4b36e8c99c0e9.tar.gz
kogata-0ea68568372b7b7b20bca6985ae4b36e8c99c0e9.zip
Implement switching to usermode.
Diffstat (limited to 'src/kernel/user/process.c')
-rw-r--r--src/kernel/user/process.c46
1 files changed, 42 insertions, 4 deletions
diff --git a/src/kernel/user/process.c b/src/kernel/user/process.c
index 7b51370..9f3e2b1 100644
--- a/src/kernel/user/process.c
+++ b/src/kernel/user/process.c
@@ -66,12 +66,50 @@ process_t *new_process(process_t *parent) {
return proc;
}
-static void run_user_code(void* data) {
- // TODO
- exit();
+static void run_user_code(void* entry) {
+ process_t *proc = current_thread->proc;
+ ASSERT(proc != 0);
+
+ switch_pagedir(proc->pd);
+
+ void* esp = (void*)USERSTACK_ADDR + USERSTACK_SIZE;
+
+ asm volatile("
+ cli;
+
+ mov $0x23, %%ax;
+ mov %%ax, %%ds;
+ mov %%ax, %%es;
+ mov %%ax, %%fs;
+ mov %%ax, %%gs;
+
+ pushl $0x23;
+ pushl %%ebx;
+ pushf;
+ pop %%eax;
+ or $0x200, %%eax;
+ pushl %%eax;
+ pushl $0x1B;
+ pushl %%ecx;
+ iret
+ "::"b"(esp),"c"(entry));
}
bool start_process(process_t *p, void* entry) {
- // TODO
+ bool stack_ok = mmap(p, (void*)USERSTACK_ADDR, USERSTACK_SIZE, MM_READ | MM_WRITE);
+ if (!stack_ok) return false;
+
+ thread_t *th = new_thread(run_user_code, entry);
+ if (th == 0) {
+ munmap(p, (void*)USERSTACK_ADDR);
+ return false;
+ }
+
+ th->proc = p;
+ th->kmem_violation_handler = proc_kmem_violation;
+
+ resume_thread(th, false);
+
+ return true;
}
// ================================== //