// http://hosted.cjmovie.net/TutMultitask.htm // // #include "kernel.h" #include "lib/logger/log.h" // logger facilities #include "lib/buffer/ringbuffer.h" #include "mem.h" #include "timer.h" #include "console.h" #include "x86.h" #include "syscalls.h" #include "fs/fs.h" #include "fs/ext2.h" #define FOOLOS_MODULE_NAME "task" #define MAX_TASKS 10 static volatile int current_task=-2; static volatile struct task_list_struct { bool active; uint32_t esp; // stack pointer of the task; uint32_t vmem; // number of virtual memory table to switch to }task_list[MAX_TASKS]; void task_create(int pid,void(*thread)()) { unsigned int *stack; task_list[pid].esp = pmmngr_alloc_block(); stack = (unsigned int*)task_list[pid].esp+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 */ task_list[pid].esp = (uint32_t)stack; //Update the stack pointer task_list[pid].active=true; }; // this gets called by our clock interrupt regularly! uint32_t task_switch_next(uint32_t oldesp) { timer_tick(); if(current_task==-2)return oldesp; if(current_task!=-1)task_list[current_task].esp=oldesp; for(int i=0;i",1); sleep(1); } } volatile void test2() { while(1) { c2++; syscall_write(1,"<",1); sleep(1); } } void task_init() { task_create(0,test1); task_create(1,test2); current_task=-1; }