summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--asm/int_clock_handler.asm2
-rw-r--r--asm/int_syscall_handler.asm30
-rw-r--r--kernel/syscalls.c20
-rw-r--r--kernel/task.c77
-rw-r--r--userspace/foolshell.c13
-rw-r--r--userspace/init.c15
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<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;
}