From 59038fc67c20a1f04e5d2fd5f9a444e707d1d3ea Mon Sep 17 00:00:00 2001 From: Miguel Date: Wed, 22 Aug 2018 00:52:30 +0200 Subject: userspace and kernelspace taskswitching --- asm/pit.s | 50 ++++++++++++++++++++++++++++---------------------- asm/task.s | 37 +++++++++++++++++++++++++++++++------ kernel/gdt.c | 10 +--------- kernel/kernel.h | 1 + kernel/mem.c | 1 - kernel/scheduler.c | 25 ++----------------------- kernel/usermode.c | 23 +++++++++++++++++------ 7 files changed, 80 insertions(+), 67 deletions(-) diff --git a/asm/pit.s b/asm/pit.s index ab8dcdb..c25e9a1 100644 --- a/asm/pit.s +++ b/asm/pit.s @@ -12,32 +12,38 @@ pit_get_ticks: pit_interrupt_handler: - // increase tick counter - push %eax - mov $ticks, %eax - incl (%eax) - pop %eax - - //// - - pusha //Push all standard registers - - mov %esp, %eax //save current stack pointer (pointing to registers!) - - movl $stack_top, %esp //use stack from multiboot.s(16Kb) + push %eax // persist - // call our scheduler passing it the old stack addres (pointing to pushed registers (pusha)) - push %eax - call task_switch_next - - // the scheduler returned the new stack pointer (after taskswitch) - mov %eax, %esp //Replace the stack with what the C code gave us + // INC TICK COUNTER + mov $ticks, %eax + incl (%eax) - // acknowlege irq - mov $0x20,%al + // ACK IRQ + mov $0x20,%al out %al,$0x20 + + pop %eax // load original - popa //Put the standard registers back + /////// + + pusha //Push all standard registers + push %ds //Push data segment + push %es //etc... + push %fs + push %gs + + mov %esp, %eax // remember current %esp + movl $stack_top, %esp // switch to our small scheduler stack + + push %eax // set original %esp as param and... + call task_switch_next // call scheduler + mov %eax, %esp // use %esp we got from scheduler + + pop %gs + pop %fs + pop %es + pop %ds + popa iret diff --git a/asm/task.s b/asm/task.s index 7611d4a..c29bdae 100644 --- a/asm/task.s +++ b/asm/task.s @@ -2,15 +2,21 @@ task_pusha: pushf - - push $0x8 + push $0x8 // code segment push $userfunc pusha + + push %ds + push %es + push %fs + push %gs + /* + now stack looks like: - param // esp+48 + param // esp+64 returnaddy eflags @@ -26,9 +32,14 @@ task_pusha: esi edi + ds + es + fs + gs + */ - mov 48(%esp),%eax // get address of alternative stack where we want to simulate the pusha + mov 64(%esp),%eax // get address of alternative stack where we want to simulate the pusha mov (%esp),%ecx mov %ecx,(%eax) @@ -66,10 +77,24 @@ task_pusha: mov 44(%esp),%ecx mov %ecx,44(%eax) + mov 48(%esp),%ecx + mov %ecx,48(%eax) + + mov 52(%esp),%ecx + mov %ecx,52(%eax) + + mov 56(%esp),%ecx + mov %ecx,56(%eax) + + pop %gs + pop %fs + pop %es + pop %ds + + popa + pop %eax pop %eax pop %eax - popa - ret diff --git a/kernel/gdt.c b/kernel/gdt.c index 06a0949..88478c7 100644 --- a/kernel/gdt.c +++ b/kernel/gdt.c @@ -1,7 +1,6 @@ // http://wiki.osdev.org/GDT_Tutorial -#include "lib/logger/log.h" +#define FOOLOS_MODULE_NAME "gdt" #include "usermode.h" -#define FOOLOS_MODULE_NAME "GDT" #include #define GDT_SIZE 6 @@ -85,13 +84,10 @@ void encodeGdtEntry(uint8_t *target, GDT source) 6 db 11001111b ;flags & seg.limit 7 db 0x0 ;base */ - - } void gdt_init() { - log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"setting up Global Descriptor Table"); //selector 0x0 myGDT[0].base=0; myGDT[0].limit=0; @@ -122,15 +118,11 @@ void gdt_init() myGDT[5].limit=sizeof(tss_struct); //tss end? myGDT[5].type=0x89; - // transcript to format the processor wants for(int i=0;i