diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/paging.c | 38 | ||||
| -rw-r--r-- | src/core/paging.h | 3 | ||||
| -rw-r--r-- | src/core/scheduler.c | 44 | ||||
| -rw-r--r-- | src/core/scheduler.h | 1 |
4 files changed, 69 insertions, 17 deletions
diff --git a/src/core/paging.c b/src/core/paging.c index 8f12866..0fab46a 100644 --- a/src/core/paging.c +++ b/src/core/paging.c @@ -88,24 +88,30 @@ char* paging_allocate_next_page(){ asm("hlt"); } - -char *paging_allocate(int p){ +// TODO: Take p into account +int *paging_allocate(int p){ + // ----- Allow kernel access during interruption int *page_dir=(int*)paging_allocate_next_page(); - int *page_table; - int current_page_entry=0; - int current_dir_entry=0; - while(current_page_entry<p){ - if(current_page_entry%1024 == 0){ - current_dir_entry++; - page_table=(int*)paging_allocate_next_page(); - page_dir[current_dir_entry]=(int)page_table; - } - int entry=current_page_entry%1024; - page_table[current_page_entry]=(int)paging_allocate_next_page(); - current_page_entry++; - print("Jean\n"); + int *k_page_table=(int*)paging_allocate_next_page(); + // Init page directory + page_dir[0]=(int)k_page_table|3; + // Init page table 0 + int addr_offset=0; + for(int i=0;i<1024;i++){ + k_page_table[i]=addr_offset; + k_page_table[i]|=3; // Permission + addr_offset+=PAGING_PAGE_SIZE; // 4Ko pages } - print("end"); + + // ----- Task table + int *u_page_table=(int*)paging_allocate_next_page(); + page_dir[1]=(int)u_page_table|7; // 1024*1024*4096/4 + u_page_table[0]=(int)page_dir|7; + u_page_table[1]=(int)k_page_table|7; + u_page_table[2]=(int)u_page_table|7; + u_page_table[3]=(int)paging_allocate_next_page()|7; + + return page_dir; } void paging_page_fault(){ diff --git a/src/core/paging.h b/src/core/paging.h index 1526101..58a33b2 100644 --- a/src/core/paging.h +++ b/src/core/paging.h @@ -9,6 +9,7 @@ #else #define PAGING_MAX_DIR_ENTRY PAGING_MAX_PAGES/1024 #endif +#define PADDR(entry) (entry&0xFFFFF000) /** * Configure and enable paging @@ -26,7 +27,7 @@ void paging_set_usage(int addr,char state); * Create a new page directory containing * p pages. */ -char *paging_allocate(int p); +int *paging_allocate(int p); void paging_dump(int min,int max); /** * Handler of page fault 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 diff --git a/src/core/scheduler.h b/src/core/scheduler.h index ec0caf1..8495e77 100644 --- a/src/core/scheduler.h +++ b/src/core/scheduler.h @@ -5,5 +5,6 @@ extern char show_tics; void clock(); void schedule(); +void run_task(int *page_dir, void *task, int task_size); #endif
\ No newline at end of file |
