aboutsummaryrefslogtreecommitdiff
path: root/src/core/scheduler.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/scheduler.c')
-rw-r--r--src/core/scheduler.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/core/scheduler.c b/src/core/scheduler.c
index 0f2b724..7b1c421 100644
--- a/src/core/scheduler.c
+++ b/src/core/scheduler.c
@@ -1,4 +1,7 @@
#include "libc/stdio.h"
+#include "gdt.h"
+#include "mem.h"
+#include "paging.h"
char show_tics=0;
@@ -17,4 +20,45 @@ void clock(){
putchar('.');
}
schedule();
+}
+
+void run_task(int *page_dir, void *task, int task_size){
+ // Compute various addresses
+ int*pt_addr=PADDR(page_dir[1]);
+ void *entry_point=(void*)(PADDR(pt_addr[3]));
+ void *ustack=(void*)((int)entry_point+0xFF);
+
+ // Load the task into memory
+ memcpy(task,entry_point, task_size);
+
+ // Load page directory
+ asm(
+ "mov %0, %%eax \n\t"
+ "mov %%eax,%%cr3 \n\t"
+ :: "b"(page_dir)
+ );
+
+ // Setup users adresses
+
+ // Switch to user task
+ asm (
+ "cli \n\t" // Ensure we do not get interrupted
+ "movl %%ss, %%eax \n\t"
+ "movl %%eax, %0 \n\t" // Save kernel ss segment into the TSS
+ "movl %%esp, %1 \n\t" // Save kernel esp into the TSS BEFORE setting up the stack
+ "pushl $0x33 \n\t" // Push task ss which is 0x30 along with prlv which is 0x3
+ "pushl %2 \n\t" // Push task esp
+ "pushfl \n\t" // Retrieve flags
+ "popl %%eax \n\t"
+ "orl $0x200, %%eax \n\t" // Enable interrupt for the user task
+ "and $0xffffbfff, %%eax \n\t" // Clear the NT flags
+ "push %%eax \n\t" // Push task flags
+ "push $0x23 \n\t" // Push task cs which is 0x20 along with prlv which is 0x3
+ "push %3 \n\t" // Push task entry point
+ "mov $0x2B, %%eax \n\t" // GDT entry 0x28 along with prlv which is 0x3
+ "mov %%eax, %%ds \n\t" // Setting up user data segment
+ "iret \n\t" // Launch user task
+ : "=m" (TSS.ss0), "=m" (TSS.esp0)
+ : "b" (ustack), "c" (entry_point)
+ );
} \ No newline at end of file