// 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)()) { task_list[pid].vmem=vmem_new_space_dir(); if(pid==0)x86_set_pdbr(0x0D08000); if(pid==1)x86_set_pdbr(0x150E000); unsigned int *stack; task_list[pid].esp = 0x8248000-4095; 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; x86_set_pdbr(0x0502000); }; // 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); } } volatile void test2() { static char *argv[]={"/bin/foolshell",NULL}; static char *env[]={"PATH=/bin","PWD=/home/miguel","PS1=$ ",NULL}; syscall_execve("/bin/task2",argv,env); while(1) { for(int i='a';i<'z';i++) { syscall_write(1,&i,1); } } } volatile void test3() { while(1) { syscall_write(1," ",1); } } void task_init() { task_create(0,test2); task_create(1,test1); // task_create(2,test3); current_task=-1; }