// http://hosted.cjmovie.net/TutMultitask.htm // // #include "kernel.h" #include "lib/logger/log.h" // logger facilities #include "lib/int/stdint.h" #include "mem.h" #include "timer.h" #include "syscalls.h" #include "fs/fs.h" #include "fs/ext2.h" #define FOOLOS_MODULE_NAME "task" int started; static uint32_t c1,c2,c3; void task_test1() { //ext2_check(EXT2_RAM_ADDRESS); //syscall_execve(15,0,0); // syscall_execve(18,0,0); while(1) { c1++; } } void task_test2() { while(1) { c2++; } } void task_test3() { while(1) { c3++; } } ////////////// // typedef struct{ //Simple structure for a thread unsigned int esp0; //Stack for kernel unsigned int esp3; //Stack for process } Thread; Thread Threads[3]; //Space for our simple threads. volatile int CurrentTask; //The thread currenlty running (-1 == none) void task_create(int pid,void(*thread)()) { unsigned int *stack; Threads[pid].esp0 = pmmngr_alloc_block(); stack = (unsigned int*)Threads[pid].esp0+4095; //This makes a pointer to the stack for us log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"new task: stack: 0x%08X thread: 0x%08X", stack, thread); //First, this stuff is pushed by the processor *--stack = 0x0202; //This is EFLAGS *--stack = 0x08; //This is CS, our code segment *--stack = (uint32_t)thread; //This is EIP //Next, the stuff pushed by 'pusha' *--stack = 0; //EDI *--stack = 0; //ESI *--stack = 0; //EBP *--stack = 0; //Just an offset, no value *--stack = 0; //EBX *--stack = 0; //EDX *--stack = 0; //ECX *--stack = 0; //EAX //Now these are the data segments pushed by the IRQ handler /* *--stack = 0x10; //DS *--stack = 0x10; //ES *--stack = 0x10; //FS *--stack = 0x10; //GS */ Threads[pid].esp0 = (uint32_t)stack; //Update the stack pointer }; uint32_t task_switch_next(uint32_t oldesp) { timer_tick(); if(started!=0xabcde) return oldesp; if(CurrentTask!=-1)Threads[CurrentTask].esp0=oldesp; CurrentTask++; if(CurrentTask>2)CurrentTask=0; log( FOOLOS_MODULE_NAME, FOOLOS_LOG_FINE, "oldesp: 0x%08X saved / next task: %d (esp: 0x%08X) ", oldesp, CurrentTask, Threads[CurrentTask].esp0); // return oldesp; return Threads[CurrentTask].esp0; //Return new stack pointer to ASM } void stack_trace(uint32_t *stack,int size) { for(int i=size;i>=0;i--) { log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"stack: 0x%08X -> 0x%08X", stack, *stack); stack++; } } void task_init() { CurrentTask=-1; log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"init multitasking."); task_create(0,task_test1); task_create(1,task_test2); task_create(2,task_test3); started=0xabcde; }