From c2c03f41e078481921bad82487eded0fc51ebb59 Mon Sep 17 00:00:00 2001 From: Michal Idziorek Date: Tue, 2 Dec 2014 01:02:49 +0100 Subject: further work on fork and friends --- Makefile | 2 +- asm/int_clock_handler.asm | 2 +- asm/int_syscall_handler.asm | 30 ++++++++++++++++-- kernel/syscalls.c | 20 ------------ kernel/task.c | 77 +++++++++++++++++++++++++++++++++------------ userspace/foolshell.c | 13 +++++++- userspace/init.c | 15 +++++---- 7 files changed, 106 insertions(+), 53 deletions(-) diff --git a/Makefile b/Makefile index 0d76522..8ffd1ef 100644 --- a/Makefile +++ b/Makefile @@ -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 [%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")) { @@ -172,6 +172,11 @@ int process(char *buf) setenv("PWD",buf,1); + } + else if(!strcmp(command,"exit")) + { + exit(1); + } else if(!strcmp(command,"echo")) { @@ -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; } -- cgit v1.2.3