diff options
| author | Miguel <m.i@gmx.at> | 2018-08-22 00:52:30 +0200 |
|---|---|---|
| committer | Miguel <m.i@gmx.at> | 2018-08-22 00:52:30 +0200 |
| commit | 59038fc67c20a1f04e5d2fd5f9a444e707d1d3ea (patch) | |
| tree | 1b0161c1b6d5caefe900f419fed31cc7d7ad6017 | |
| parent | 72c6e9763ca61bc9d7de5f7080ee1c8a1c7c1562 (diff) | |
userspace and kernelspace taskswitching
| -rw-r--r-- | asm/pit.s | 50 | ||||
| -rw-r--r-- | asm/task.s | 37 | ||||
| -rw-r--r-- | kernel/gdt.c | 10 | ||||
| -rw-r--r-- | kernel/kernel.h | 1 | ||||
| -rw-r--r-- | kernel/mem.c | 1 | ||||
| -rw-r--r-- | kernel/scheduler.c | 25 | ||||
| -rw-r--r-- | kernel/usermode.c | 23 |
7 files changed, 80 insertions, 67 deletions
@@ -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 @@ -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 <stdint.h> #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<GDT_SIZE;i++) encodeGdtEntry(&gdt_struct[8*i],myGDT[i]); - // updat install_tss(); setup_gdt(&gdt_struct[0],8*GDT_SIZE); - - } diff --git a/kernel/kernel.h b/kernel/kernel.h index 1880045..5ac10d1 100644 --- a/kernel/kernel.h +++ b/kernel/kernel.h @@ -11,6 +11,7 @@ #define FIFO_MAX_RINGBUFFERS 20 #define MAX_FIFOS 20 #define MAX_FD 20 +#define MAX_TASKS 255 #define FOOLOS_CONSOLE_AUTOBREAK // add newline automatically at end of line diff --git a/kernel/mem.c b/kernel/mem.c index a167d8b..8b90911 100644 --- a/kernel/mem.c +++ b/kernel/mem.c @@ -219,7 +219,6 @@ uint32_t mem_init(multiboot_information *info) // we deinit everything below mem_min_block anyway pmmngr_deinit_region(0,mem_min_block*PMMNGR_BLOCK_SIZE); - log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Usable ~%d / %d MB ",mem_free_blocks*4096/1024/1024,total_mem/1024/1024); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO, diff --git a/kernel/scheduler.c b/kernel/scheduler.c index 4823276..d6e2c76 100644 --- a/kernel/scheduler.c +++ b/kernel/scheduler.c @@ -13,8 +13,6 @@ #include "fs/fs.h" #include "fs/ext2.h" -#define MAX_TASKS 10 - static volatile int volatile current_task=-1; static volatile struct task_list_struct @@ -36,7 +34,6 @@ volatile int add_task(uint32_t esp, uint32_t vmem) { if(task_list[i].active!=true) { - task_list[i].parent=current_task; task_list[i].vmem=vmem; task_list[i].esp=esp; @@ -174,30 +171,12 @@ volatile void scheduler_init(pdirectory *dir) task_list[1].vmem=dir; task_list[1].esp = kballoc(4); // fresh 16kb stack from here. - log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"fresh esp on: 0x%08X",1,task_list[1].esp); - log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"fresh esp on: 0x%08X",0,task_list[0].esp); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"fresh esp on: 0x%08X",task_list[1].esp+4*4096-1); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"fresh esp on: 0x%08X",task_list[0].esp+4*4096-1); task_pusha(task_list[1].esp); // pusha but to alternative location task_pusha(task_list[0].esp); // pusha but to alternative location - /* - current_task=0; - unsigned esp, ebp, eax, ebx, ecx, edx; - - asm( - "movl %%esp, %0;" - "movl %%ebp, %1;" - "movl %%eax, %2;" - "movl %%ebx, %3;" - "movl %%ecx, %4;" - "movl %%edx, %5;" - :"=r"(esp), "=r"(ebp), "=r"(eax), "=r"(ebx), "=r"(ecx), "=r"(edx) - ); - - // TODO: prepare stack so popa get's what it wants! - int i=task_fork(esp); - */ - // finally enable interrrupts so the scheduler is called (by timer) x86_sti(); diff --git a/kernel/usermode.c b/kernel/usermode.c index 81dc5c1..bb614d0 100644 --- a/kernel/usermode.c +++ b/kernel/usermode.c @@ -15,6 +15,9 @@ //https://wiki.osdev.org/Task_State_Segment tss_struct sys_tss; //Define the TSS as a global structure +static volatile uint32_t c1; +static volatile uint32_t c2; + void install_tss(int cpu_no){ // now fill each value @@ -28,20 +31,28 @@ void install_tss(int cpu_no){ void userfunc() { + // we need enable here again (since the pushed eflags have it disabled)! x86_sti(); // if we are pid 0, replace ourselves with /bin/init TODO: switch to usermode before! - if(task_get_current_pid()==0)syscall(SYSCALL_EXECVE,BIN_INIT,NULL,NULL); + if(task_get_current_pid()==0) + { + //usermode(&initfunc); + while(1) + { + c2++; + } + } - // kernel worker thread + // kernel worker thread on pid1 if(task_get_current_pid()==1) { + while(1) + { + c1++; + } } } -void switch_to_user_mode() -{ - usermode(&userfunc); -} |
