diff options
| author | Michal Idziorek <m.i@gmx.at> | 2014-12-02 01:02:49 +0100 |
|---|---|---|
| committer | Michal Idziorek <m.i@gmx.at> | 2014-12-02 01:02:49 +0100 |
| commit | c2c03f41e078481921bad82487eded0fc51ebb59 (patch) | |
| tree | 1e310556c9a809aea112728bae9e0a6807ee0ba2 | |
| parent | f20db37ca17245d5d20302a1ac1da347de5c3607 (diff) | |
further work on fork and friends
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | asm/int_clock_handler.asm | 2 | ||||
| -rw-r--r-- | asm/int_syscall_handler.asm | 30 | ||||
| -rw-r--r-- | kernel/syscalls.c | 20 | ||||
| -rw-r--r-- | kernel/task.c | 77 | ||||
| -rw-r--r-- | userspace/foolshell.c | 13 | ||||
| -rw-r--r-- | userspace/init.c | 15 |
7 files changed, 106 insertions, 53 deletions
@@ -35,7 +35,7 @@ CFLAGS+=-ffreestanding CFLATS+=-Wall CFLAGS+=-Wextra #CFLAGS+=-O3 -#CFLAGS+=-O0 +CFLAGS+=-O0 #CFLAGS+=-nostdlib CFLAGS+=-std=gnu11 CFLAGS+=-I. diff --git a/asm/int_clock_handler.asm b/asm/int_clock_handler.asm index 6301dc6..5e48658 100644 --- a/asm/int_clock_handler.asm +++ b/asm/int_clock_handler.asm @@ -9,7 +9,7 @@ cli pusha ;Push all standard registers mov eax, esp ;save current stack pointer in esp -mov esp, 0x1000 ;now put the stack outside of virtual memory in kernel space! +mov esp, 0x7000 ;now put the stack outside of virtual memory in kernel space! push eax ;Push pointer to all the stuff we just pushed call task_switch_next ;Call C code diff --git a/asm/int_syscall_handler.asm b/asm/int_syscall_handler.asm index 504d3e8..70090f0 100644 --- a/asm/int_syscall_handler.asm +++ b/asm/int_syscall_handler.asm @@ -1,6 +1,7 @@ global int_syscall_handler [extern task_fork] [extern task_exit] +[extern task_wait] [extern syscall_exit] @@ -25,13 +26,15 @@ pid: dd 0x0 int_syscall_handler: - cmp eax, 72 je call_fork cmp eax, 60 je call_exit +cmp eax, 77 +je call_wait + cli push ebx @@ -96,12 +99,35 @@ done_blocking: iret ;Interrupt-Return +call_wait: + + cli + + pusha ;Push all standard registers + + mov ebx, esp ;save current stack pointer in esp + mov esp, 0x7000 ;now put the stack outside of virtual memory in kernel space! + + push ebx ;Push pointer to all the stuff we just pushed + + call task_wait ;Call C code + + mov esp, eax ;Replace the stack with what the C code gave us + + popa ;Put the standard registers back + + sti + + iretd ;Interrupt-Return + ;;;; + call_exit: cli pusha ;Push all standard registers + mov ebx, esp ;save current stack pointer in esp mov esp, 0x7000 ;now put the stack outside of virtual memory in kernel space! push ebx ;Push pointer to all the stuff we just pushed @@ -126,7 +152,7 @@ call_fork: mov ebx, esp ;save current stack pointer in esp mov esp, 0x7000 ;now put the stack outside of virtual memory in kernel space! - push ebx ;Push pointer to all the stuff we just pushed + push ebx call task_fork ;Call C code mov [pid],eax diff --git a/kernel/syscalls.c b/kernel/syscalls.c index 41d77ec..44b04bd 100644 --- a/kernel/syscalls.c +++ b/kernel/syscalls.c @@ -120,15 +120,6 @@ int syscall_readdir(const char *name,fs_dirent *dirs,int max) return fs_readdir(name,dirs,max); } -int syscall_wait(int *wait, int none1, int none2) -{ - #ifdef LOG_SYSCALLS - log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"[%d] wait ",task_get_current_pid()); - #endif - - panic(FOOLOS_MODULE_NAME,"unhandled syscall"); -} - int syscall_execve(char *name, char **argv1, char **env1) { char *argv[]={"/bin/foolshell",NULL}; @@ -221,17 +212,6 @@ uint32_t syscall_sbrk(int incr, int none1, int none2) } -int syscall_exit(int ret, char **env, int none2) -{ - #ifdef LOG_SYSCALLS - log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"exit (ret=%d) (env=0x%08X)", ret, env); - #endif - - panic(FOOLOS_MODULE_NAME,"exit not supported yet" ); - -} - - // stat, fstat, lstat int syscall_stat(const char *path, struct stat *st,int none) { diff --git a/kernel/task.c b/kernel/task.c index 6ea9b79..ac54dbe 100644 --- a/kernel/task.c +++ b/kernel/task.c @@ -17,7 +17,7 @@ #define MAX_TASKS 10 -static volatile int current_task=-2; +static volatile int current_task=-1; static volatile struct task_list_struct { @@ -25,6 +25,8 @@ 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 + bool waiting; + bool skipwait; }volatile task_list[MAX_TASKS]; @@ -40,6 +42,8 @@ int add_task(uint32_t esp, uint32_t vmem) task_list[i].vmem=vmem; task_list[i].esp=esp; task_list[i].active=true; + task_list[i].waiting=false; + task_list[i].skipwait=false; return i; } @@ -48,22 +52,19 @@ int add_task(uint32_t esp, uint32_t vmem) panic(FOOLOS_MODULE_NAME,"out of task slots!"); } -// this gets called by our clock interrupt regularly! -uint32_t task_switch_next(uint32_t oldesp) +uint32_t my_scheduler(uint32_t oldesp) { - timer_tick(); - - if(current_task==-2)return oldesp; - task_list[current_task].esp=oldesp; - + for(int i=0;i<MAX_TASKS;i++) { int pid=(current_task+1+i)%MAX_TASKS; // schedule round robin style - if(task_list[pid].active) + if(task_list[pid].active && !task_list[pid].waiting) { - // log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"switch from %d to pid: %d (0x%08X) vmem: %d ", current_task,pid,task_list[pid].esp,task_list[pid].vmem); + // if(current_task!=pid) + // log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"switch from %d to %d", current_task, pid); + current_task=pid; vmem_set_dir(task_list[pid].vmem); @@ -72,34 +73,68 @@ uint32_t task_switch_next(uint32_t oldesp) } - return oldesp; + panic(FOOLOS_MODULE_NAME,"nothing to schedule!"); +} + +// this gets called by our clock interrupt regularly! +uint32_t task_switch_next(uint32_t oldesp) +{ + timer_tick(); + + // check if multitasking has been started + if(current_task<0)return oldesp; + + return my_scheduler(oldesp); } + //TODO: free vmem too! +//TODO: notify waiting parent when child finished; uint32_t task_exit(uint32_t oldesp) { task_list[current_task].active=false; + int parent_pid=task_list[current_task].parent; - for(int i=0;i<MAX_TASKS;i++) + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"[%d] exit ", current_task); + if(task_list[parent_pid].active) { - int pid=(current_task+1+i)%MAX_TASKS; // schedule round robin style - - if(task_list[pid].active) + if(task_list[parent_pid].waiting) { - // log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"switch from %d to pid: %d (0x%08X) vmem: %d ", current_task,pid,task_list[pid].esp,task_list[pid].vmem); - current_task=pid; - - vmem_set_dir(task_list[pid].vmem); - return task_list[pid].esp; + + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"wakeing up %d ", parent_pid); + task_list[parent_pid].waiting=false; + } + else + { + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"set skipwait on %d ", parent_pid); + task_list[parent_pid].skipwait=true; } + + } + + return my_scheduler(oldesp); + +} +uint32_t task_wait(uint32_t oldesp) +{ + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"[%d] wait", current_task); + if(task_list[current_task].skipwait) + { + task_list[current_task].skipwait=false; + } + else + { + task_list[current_task].waiting=true; } + return my_scheduler(oldesp); } uint32_t task_fork(uint32_t oldesp) { int pid=add_task(oldesp,vmem_new_space_dir(task_list[current_task].vmem)); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"[%d] forked -> [%d]", current_task, pid); return pid; } @@ -107,7 +142,9 @@ uint32_t task_fork(uint32_t oldesp) void task_init() { // this is our main task on slot 0 + task_list[0].parent=0; task_list[0].active=true; + task_list[0].waiting=false; task_list[0].vmem=0; task_list[0].esp = 0; // will be set by next task_switch_next() call. current_task=0; diff --git a/userspace/foolshell.c b/userspace/foolshell.c index 78ba327..7d2291e 100644 --- a/userspace/foolshell.c +++ b/userspace/foolshell.c @@ -109,7 +109,7 @@ int process(char *buf) if(!strcmp(command,"help")) { - puts("foolshell: supported built-in commands: 'help', 'echo [string]', 'malloc [bytes]', 'free [address]', 'getenv [var]', 'putenv/setenv [var] [val]', 'env' 'cd [dir]'"); + puts("foolshell: supported built-in commands: 'help', 'echo [string]', 'malloc [bytes]', 'free [address]', 'getenv [var]', 'putenv/setenv [var] [val]', 'env' 'cd [dir]', 'exit'"); } else if(!strcmp(command,"cd")) { @@ -173,6 +173,11 @@ int process(char *buf) setenv("PWD",buf,1); } + else if(!strcmp(command,"exit")) + { + exit(1); + + } else if(!strcmp(command,"echo")) { printf("\"%s\"\n",token[1]); @@ -215,12 +220,18 @@ int process(char *buf) if(pid!=0) { printf("new task pid: %i \n",pid); + } + if(pid==0) + { char buf[256]; sprintf(buf,"%s/%s",getenv("PATH"),token[0]); + sprintf(buf,"%s/%s","/bin",token[0]); execve(buf,token,environ); puts("foolshell: command not found"); exit(1); } + int status; + wait(&status); } return 0; diff --git a/userspace/init.c b/userspace/init.c index fd562a9..8c3bcd7 100644 --- a/userspace/init.c +++ b/userspace/init.c @@ -1,21 +1,20 @@ + int main(int argc, char **argv) { int pid=fork(); - if(pid!=0) + if(pid==0) { - printf("fool-init: forked child (pid: %i) spawning a Fools Shell\n",pid); execve("/bin/foolshell",0,0); - } else { - // TODO: wait for child and respawn shell if needed! - volatile int i=0; - while(1) - { + printf("fool-init: forked child (pid: %i) spawning a Fools Shell\n",pid); + int status; + int pid_ret=wait(&status); + puts("child state has changed!"); + execve("/bin/init",0,0); - } } return 0; } |
