// http://hosted.cjmovie.net/TutMultitask.htm // // #include "kernel.h" #include "lib/logger/log.h" // logger facilities #include "lib/int/stdint.h" #define FOOLOS_MODULE_NAME "task" int started; void task_test1() { uint32_t c; while(1) { c++; while(1)PutString("task0: %d", 00,500,0b1111100000000000, (c++)); } } void task_test2() { uint32_t c; while(1) { c++; while(1)PutString("task1: %d", 200,500,0b1111100000000000, (c++)); } } ////////////// // typedef struct{ //Simple structure for a thread unsigned int esp0; //Stack for kernel unsigned int esp3; //Stack for process } Thread; Thread Threads[2]; //Space for our simple threads. Just 2! int CurrentTask = -1; //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+4000; //This makes a pointer to the stack for us log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"new task : stack: 0x%08X ", stack); //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) { if(started!=0xabcde) return oldesp; if(CurrentTask != -1){ //Were we even running a task? Threads[CurrentTask].esp0 =oldesp; //Save the new esp for the thread //Now switch what task we're on if(CurrentTask == 0)CurrentTask = 1; else CurrentTask = 0; } else{ CurrentTask = 0; //We just started multi-tasking, start with task 0 } uint32_t esp=0; log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"oldesp: 0x%08X saved / next task: %d (esp: 0x%08X) ",oldesp, CurrentTask,Threads[CurrentTask].esp0); 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() { log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"init multitasking."); task_create(0,task_test1); task_create(1,task_test2); started=0xabcde; }