summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/fifo.c38
-rw-r--r--kernel/fifo.h23
-rw-r--r--kernel/kernel.c17
-rw-r--r--kernel/log.c1
-rw-r--r--kernel/scheduler.c20
-rw-r--r--kernel/syscalls.c273
-rw-r--r--kernel/syscalls.h40
7 files changed, 152 insertions, 260 deletions
diff --git a/kernel/fifo.c b/kernel/fifo.c
deleted file mode 100644
index 10bc8ff..0000000
--- a/kernel/fifo.c
+++ /dev/null
@@ -1,38 +0,0 @@
-#include "kernel.h"
-#include "log.h"
-#include "fifo.h"
-
-#include "ringbuffer.h"
-
-#include <stddef.h>
-
-static ringbuffer fifo_ringbuffers[FIFO_MAX_RINGBUFFERS];
-static ringbuffer_c=0;
-
-bool fifo_put(fifo* f,uint8_t c)
-{
- return f->put(f->data,c);
-}
-
-uint8_t fifo_get(fifo* f)
-{
- return f->get(f->data);
-}
-
-bool fifo_has(fifo* f)
-{
- return f->has(f->data);
-}
-
-fifo fifo_create_buffered(uint8_t size)
-{
- if (ringbuffer_c>=FIFO_MAX_RINGBUFFERS) kpanic("ran out of ringbuffers for fifos");
- fifo f;
- fifo_ringbuffers[ringbuffer_c]=ringbuffer_init(size);
- f.data=&fifo_ringbuffers[ringbuffer_c];
- ringbuffer_c++;
- f.put=ringbuffer_put;
- f.get=ringbuffer_get;
- f.has=ringbuffer_has;
- return f;
-}
diff --git a/kernel/fifo.h b/kernel/fifo.h
deleted file mode 100644
index 92f3b75..0000000
--- a/kernel/fifo.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// SIMPLE FIFO DRIVER //
-
-#ifndef FIFO_H
-#define FIFO_H
-
-#include <stdint.h>
-#include <stdbool.h>
-
-typedef struct fifo_struct
-{
- bool (*put)(struct fifo_struct*,uint8_t);
- uint8_t (*get)(struct fifo_struct*);
- bool (*has)(struct fifo_struct*);
- void *data; // opaque data
-
-}fifo;
-
-bool fifo_put(fifo*,uint8_t);
-uint8_t fifo_get(fifo*);
-bool fifo_has(fifo*);
-
-fifo fifo_create_buffered(uint8_t size);
-#endif
diff --git a/kernel/kernel.c b/kernel/kernel.c
index ba968d5..2e2e3e6 100644
--- a/kernel/kernel.c
+++ b/kernel/kernel.c
@@ -119,24 +119,11 @@ void kernel_main(uint32_t eax,uint32_t ebx)
uint32_t addr= ext2_inode_blockstart( VMEM_EXT2_RAMIMAGE,inode,0);
vesa_init(cfg_multiboot->vbe_control_info,cfg_multiboot->vbe_mode_info,addr);
- // -- STDIN/STDOUT -- //
- fixme("do not force order"); // now needed since ids are allocated 0,1,2...
- klog("Streams and Pipes init ...");
- uint32_t sstderr = syscall_open("~stderr",0,0); // stderr 2
- uint32_t sstdout;
- if(cfg_multiboot->framebuffer_type==2) // EGA-standard text mode
- {
- sstdout = syscall_open("~term",0,0); // stdout 1
- }
- else
- {
- sstdout = syscall_open("~xterm",0,0); // stdout 1
- }
- uint32_t sstdin = syscall_open("~stdin",0,0); // stdin 0
-
+ // -- KB -- //
klog("Keyboard init ...");
keyboard_init(0);
+ // -- MOUSE -- //
klog("Mouse init ...");
mouse_init();
diff --git a/kernel/log.c b/kernel/log.c
index 952c271..2e14dff 100644
--- a/kernel/log.c
+++ b/kernel/log.c
@@ -8,7 +8,6 @@
#include "spinlock.h"
#include "kernel/kernel.h"
-#include "kernel/fifo.h"
#include "driver/serial.h"
#include "driver/timer.h"
diff --git a/kernel/scheduler.c b/kernel/scheduler.c
index e834afc..56f6bbc 100644
--- a/kernel/scheduler.c
+++ b/kernel/scheduler.c
@@ -23,13 +23,13 @@
//TODO: ugly!
extern ringbuffer kb_in;
-static volatile uint32_t pid=1000;
+static volatile uint32_t pid=0;
static uint32_t nextPID()
{
spinlock_spin(SPINLOCK_PID);
- pid++;
uint32_t ret=pid;
+ pid++;
spinlock_release(SPINLOCK_PID);
return ret;
}
@@ -40,19 +40,19 @@ static volatile uint32_t current_task[SMP_MAX_PROC];
// we hold this stuff per cpu
static volatile struct task_list_struct
{
- volatile bool active; // is this slot used (Y/N)
+ volatile bool active; // is this slot used (Y/N)
volatile uint32_t pid; // process id
volatile uint32_t parent; // parent process id
volatile uint32_t esp; // stack pointer of the task
volatile uint32_t esp0; // tss.esp0
- volatile struct pdirectory *vmem; // number of virtual memory table
+ volatile struct pdirectory *vmem; // number of virtual memory table
volatile uint32_t brk; // memory brk pos
- volatile bool try; // waiting coz syscall not processed yet
- volatile bool syscall; // syscall in progress
- volatile uint32_t eax;
+ volatile bool try; // try to process syscall
+ volatile bool syscall; // syscall not processed yet
+ volatile uint32_t eax; // syscall details
volatile uint32_t ebx;
volatile uint32_t ecx;
volatile uint32_t edx;
@@ -78,10 +78,12 @@ volatile void scheduler_init(uint32_t cpu, void *dir)
task_list[cpu][0].pid=nextPID();
task_list[cpu][0].active=true;
task_list[cpu][0].syscall=false;
- task_list[cpu][1].thread=false;
+ task_list[cpu][0].thread=false;
task_list[cpu][0].vmem=dir;
task_list[cpu][0].esp = VMEM_CPU_STACK_TOP-0x200;
task_list[cpu][0].esp0 = 0; // esp0 not needed by kernel space tasks
+ fd_init_std_streams(task_list[cpu][0].pid);
+
// this will go to userspace
task_list[cpu][1].parent=0;
@@ -92,6 +94,7 @@ volatile void scheduler_init(uint32_t cpu, void *dir)
task_list[cpu][1].vmem=dir;
task_list[cpu][1].esp = kballoc(4)+4*4096-0x200; // 4 pages stack
task_list[cpu][1].esp0 =kballoc(4)+4*4096; // esp0 not needed by kernel space tasks
+ fd_init_std_streams(task_list[cpu][1].pid);
// sleeper
@@ -103,6 +106,7 @@ volatile void scheduler_init(uint32_t cpu, void *dir)
task_list[cpu][2].vmem=dir;
task_list[cpu][2].esp = kballoc(4)+4*4096-0x200; // 4 pages stack
task_list[cpu][2].esp0 =kballoc(4)+4*4096; // esp0 not needed by kernel space tasks
+ fd_init_std_streams(task_list[cpu][2].pid);
// stacks
task_pusha(task_list[cpu][0].esp);
diff --git a/kernel/syscalls.c b/kernel/syscalls.c
index b5dd6df..dfcdaae 100644
--- a/kernel/syscalls.c
+++ b/kernel/syscalls.c
@@ -1,3 +1,5 @@
+// remember to sync this with interface/syscalls.c
+
#include "lib/string/string.h"
#include "lib/printf/printf.h"
#include "fs/ext2.h"
@@ -20,6 +22,30 @@
#include "mem.h"
#include "reent.h"
#include "errno.h"
+#include "stdstreams.h"
+
+#define MAX_PID 200
+
+//TODO move to process.c and implement per process //
+static fd fds[MAX_PID][MAX_FD];
+static uint32_t next_fd[MAX_PID];
+
+void fd_init_std_streams(uint32_t pid)
+{
+ if(pid==0)
+ {
+ //stdin / stdout /stderr
+ fds[0][next_fd[0]++]=fd_from_ringbuffer();
+ fds[0][next_fd[0]++]=fd_from_fb_term();
+ fds[0][next_fd[0]++]=fd_from_fb_term();
+ }
+ else
+ {
+ fds[pid][0]=fds[0][0];
+ fds[pid][1]=fds[0][1];
+ fds[pid][2]=fds[0][2];
+ }
+}
/** errno helper */
void set_errno(int no)
@@ -28,17 +54,7 @@ void set_errno(int no)
impure_ptr->_errno=no;
}
-static fd fds[MAX_FD];
-static uint32_t next_fd=0;
-
-// fifos for backing up some file descrpitors
-static fifo fifos[MAX_FIFOS];
-static uint32_t next_fifo=0;
-
-// screen / terminal
-term_out screen;
-terminal_tty tty1;
-
+/** get string represnation of syscall */
char* syscall_get_name(uint32_t num)
{
switch(num)
@@ -89,18 +105,13 @@ char* syscall_get_name(uint32_t num)
return "SYSCALL_CLONE";
case 84:
return "SYSCALL_PIPE";
+ case 86:
+ return "SYSCALL_DUP2";
}
- return "UNKNOWN SYSCALL NUM";
-}
-
-int syscall_unhandled(int nr)
-{
- char msg[256];
- tfp_sprintf(msg, "unhandled syscall : %d",nr);
- kpanic("%s",msg);
+ kpanic("UNKNOWN SYSCALL NUM");
}
-int syscall_gettimeofday(struct timeval *tv, struct timezone *tz)
+int syscall_gettimeofday(struct timeval *tv, struct timezone *tz,uint32_t none1, uint32_t pid)
{
if(tv!=NULL)
{
@@ -118,7 +129,7 @@ int syscall_gettimeofday(struct timeval *tv, struct timezone *tz)
return 0;
}
-int syscall_lseek(int file,int ptr,int dir)
+int syscall_lseek(int file,int ptr,int dir,uint32_t pid)
{
#ifndef SEEK_SET
@@ -133,7 +144,7 @@ int syscall_lseek(int file,int ptr,int dir)
if(dir==SEEK_CUR)
{
- uint32_t *dat=fds[file].data;
+ uint32_t *dat=fds[pid][file].data;
dat[1]+=ptr;
return dat[1];
}
@@ -143,11 +154,11 @@ int syscall_lseek(int file,int ptr,int dir)
}
// TODO: /dev/console or /dev/tty1 - /dev/ttyN
-int syscall_write(int file, char *buf, int len)
+int syscall_write(int file, char *buf, int len,uint32_t pid)
{
for(int i=0;i<len;i++)
{
- fd_write(&fds[file],buf[i]);
+ fd_write(&fds[pid][file],buf[i]);
}
return len;
}
@@ -156,15 +167,15 @@ int syscall_write(int file, char *buf, int len)
* __read()__ attemts to read up to _len_ bytes from file descriptor _file_
* into the buffer starting at _buf_.
*/
-int syscall_read(int file, char *buf, int len)
+int syscall_read(int file, char *buf, int len,uint32_t pid)
{
- if(fd_eof(&fds[file]))return 0;
- *buf=fd_read(&fds[file]);
+ if(fd_eof(&fds[pid][file]))return 0;
+ *buf=fd_read(&fds[pid][file]);
return 1;
}
//TODO: replace with dirent!
-int syscall_readdir(const char *name,fs_dirent *dirs,int *pos)
+int syscall_readdir(const char *name,fs_dirent *dirs,int *pos,uint32_t pid)
{
int ret=mount_read_dir(name, dirs, pos);
if(ret==-1)
@@ -174,35 +185,7 @@ int syscall_readdir(const char *name,fs_dirent *dirs,int *pos)
return ret;
}
-// for non blocking io?
-int syscall_poll(int file)
-{
- file=2; //workaround
-
- return fd_has(&fds[file]);
-}
-
-// TODO: DELETE THIS SHIT!
-int syscall_tune(int v1,int v2, int v3)
-{
-
- // osbolete
- /*
- if(v1==0) // regular tty mode
- {
- get_fool()->tty->set_buff=true;
- get_fool()->tty->set_echo=true;
- }
- if(v1==1) // gaming tty mode
- {
- get_fool()->tty->set_buff=false;
- get_fool()->tty->set_echo=false;
- }
- */
-
- return 0;
-}
-
+/** execve helper */
int copy_args(char **in, char **out)
{
//klog("copy_args(0x%08x, 0x%08X)",in,out);
@@ -233,6 +216,7 @@ int copy_args(char **in, char **out)
}
/** does not return on success otherwise -1 and errrno set */
+// int execve(const char *filename, char *const argv[], char *const envp[]);
int syscall_execve(const char *name, char *const argv[], char *const env[], int pid)
{
@@ -264,98 +248,54 @@ int syscall_execve(const char *name, char *const argv[], char *const env[], int
return 0;
}
-// minihack
-int get_max_fd()
+int syscall_open(char *name, int flags, int mode,uint32_t pid)
{
- return next_fd-1;
+ fds[pid][next_fd[pid]]=mount_file_open(name);
+ if(*(uint32_t *)fds[pid][next_fd[pid]].data==0)return -1;
+
+ next_fd[pid]++;
+ return next_fd[pid]-1;
}
-// TODO: support other files too (not only fifo pipes)
-// TODO: allow opening existing files/named pipes
-int syscall_open(char *name, int flags, int mode)
+// pid_t fork(void);
+uint32_t syscall_fork(int none1, int none2, int none3, int pid)
{
- if( next_fifo>=MAX_FIFOS || next_fd>=MAX_FD)kpanic("we ran out of fd's or fifo's");
-
- bool create_fifo=true;
- if(name[0]!='~')create_fifo=false;
-
- if(create_fifo)
- {
-
- if(!strcmp(name,"~term"))
- {
- screen.put_char=console_put_char;
- screen.update_cursor=update_cursor;
-
- tty1=terminal_init(&screen,NULL);
-
- fifos[next_fifo].data=&tty1;
- fifos[next_fifo].put=terminal_put;
-
- fds[next_fd]=fd_from_fifo(&fifos[next_fifo]);
- }
- else if(!strcmp(name,"~xterm"))
- {
- screen.put_char=vesa_console_put_char;
- screen.update_cursor=vesa_update_cursor;
-
- tty1=terminal_init(&screen,NULL);
-
- fifos[next_fifo].data=&tty1;
- fifos[next_fifo].put=terminal_put;
-
- fds[next_fd]=fd_from_fifo(&fifos[next_fifo]);
- }
- else
- {
- fifos[next_fifo]=fifo_create_buffered(1);
- fds[next_fd]=fd_from_fifo(&fifos[next_fifo]);
- }
-
- next_fifo++;
- }
- else
- {
- fds[next_fd]=mount_file_open(name);
- if(*(uint32_t *)fds[next_fd].data==0)return -1;
- }
-
- next_fd++;
- return next_fd-1;
+ uint32_t newpid=task_fork(pid);
+ fds[newpid][0]=fds[pid][0];
+ fds[newpid][1]=fds[pid][1];
+ fds[newpid][2]=fds[pid][2];
+ return newpid;
}
-uint32_t syscall_fork(int pid)
-{
- return task_fork(pid);
-}
-uint32_t syscall_clone(int pid)
+uint32_t syscall_clone(int none1, int none2, int none3, int pid)
{
return task_clone(pid);
}
-uint32_t syscall_wait(int pid)
+uint32_t syscall_wait(int none1, int none2, int none3, int pid)
{
return 0;
}
-uint32_t syscall_exit(int pid)
+// void _exit(int status)
+uint32_t syscall_exit(int status, uint32_t none1, uint32_t none2,int pid)
{
fixme("free allll mem");
+ klog("pid %d exited with %d",pid,status);
task_exit(pid);
return 0;
}
-//newcomers
-//
-int syscall_close(int file,int none1,int none2)
+// int close (int fd) (TODO; close or not to close open filedescirptors?)
+int syscall_close(int file,int none1,int none2,int pid)
{
if(file<3)return 0;
- fd_close(&fds[file]);
+ fd_close(&fds[pid][file]);
return 0;
}
-// TODO: check if file is termminal!
-int syscall_isatty(int file,int none1,int none2)
+// TODO: check if file is a termminal!
+int syscall_isatty(int file,int none1,int none2,int pid)
{
return 1;
}
@@ -372,83 +312,86 @@ uint32_t syscall_sbrk(uint32_t incr, int none1, int none2, uint32_t pid)
}
// stat, fstat, lstat
-int syscall_stat(const char *path, struct stat *st,int none)
+int syscall_stat(const char *path, struct stat *st,int none,uint32_t pid)
{
st->st_mode = S_IFCHR;
return 0;
}
-/// there also is task_fork, task_wait, task_exit.. which is in scheduler.c
-////////////////////////////////////////
-uint32_t syscall_generic_test(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid)
-{
- switch(nr){
- case SYSCALL_WAIT :
- return !task_runs(p1);
- case SYSCALL_READ :
- return fd_has(&fds[p1]);
- case SYSCALL_EXIT :
- return 1;
- }
- return 1;
-}
-uint32_t syscall_pipe(uint32_t *addr)
+uint32_t syscall_pipe(uint32_t *addr,int none1, int none2, uint32_t pid)
{
- if( next_fifo>=MAX_FIFOS || next_fd>=MAX_FD)kpanic("we ran out of fd's or fifo's");
fd pipfds[2];
int ret=fds_from_pipe(pipfds);
- fds[next_fd]=pipfds[0] ;
- *addr=next_fd;
+ fds[pid][next_fd[pid]]=pipfds[0] ;
+ *addr=next_fd[pid];
addr++;
- next_fd++;
- if( next_fifo>=MAX_FIFOS || next_fd>=MAX_FD)kpanic("we ran out of fd's or fifo's");
+ next_fd[pid]++;
- fds[next_fd]=pipfds[1] ;
- *addr=next_fd;
- next_fd++;
+ fds[pid][next_fd[pid]]=pipfds[1] ;
+ *addr=next_fd[pid];
+ next_fd[pid]++;
return ret;
+}
+
+uint32_t syscall_dup2(uint32_t oldfd,int newfd, int none2, uint32_t pid)
+{
+ fds[pid][newfd]=fds[pid][oldfd];
+ return newfd;
+}
+
+/** Generics */
+uint32_t syscall_generic_test(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid)
+{
+ switch(nr){
+ case SYSCALL_WAIT :
+ return !task_runs(p1);
+ case SYSCALL_READ :
+ return fd_has(&fds[pid][p1]);
+ }
+ return 1;//other syscalls never block for now.
}
+/** Generics */
uint32_t syscall_generic(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid)
{
switch(nr){
case SYSCALL_EXIT :
- return syscall_exit(pid);
+ return syscall_exit(p1,p2,p3,pid);
case SYSCALL_CLOSE :
- return syscall_close(p1,p2,p3);
+ return syscall_close(p1,p2,p3,pid);
case SYSCALL_EXECVE :
return syscall_execve(p1,p2,p3,pid);
case SYSCALL_FORK :
- return syscall_fork(pid);
+ return syscall_fork(p1,p2,p3,pid);
case SYSCALL_CLONE :
- return syscall_clone(pid);
+ return syscall_clone(p1,p2,p3,pid);
case SYSCALL_GETPID :
// return syscall_getpid(p1,p2,p3);
return -1;
case SYSCALL_ISATTY :
- return syscall_isatty(p1,p2,p3);
+ return syscall_isatty(p1,p2,p3,pid);
case SYSCALL_LINK :
// return syscall_link(p1,p2,p3);
return -1;
case SYSCALL_LSEEK :
- return syscall_lseek(p1,p2,p3);
+ return syscall_lseek(p1,p2,p3,pid);
case SYSCALL_OPEN :
- return syscall_open(p1,p2,p3);
+ return syscall_open(p1,p2,p3,pid);
case SYSCALL_READ :
- return syscall_read(p1,p2,p3);
+ return syscall_read(p1,p2,p3,pid);
case SYSCALL_SBRK :
return syscall_sbrk(p1,p2,p3,pid);
case SYSCALL_STAT :
- return syscall_stat(p1,p2,p3);
+ return syscall_stat(p1,p2,p3,pid);
case SYSCALL_FSTAT :
- return syscall_stat(p1,p2,p3);
+ return syscall_stat(p1,p2,p3,pid);
case SYSCALL_LSTAT :
- return syscall_stat(p1,p2,p3);
+ return syscall_stat(p1,p2,p3,pid);
case SYSCALL_TIMES :
// return syscall_times(p1,p2,p3);
return -1;
@@ -456,18 +399,20 @@ uint32_t syscall_generic(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint
// return syscall_unlink(p1,p2,p3);
return -1;
case SYSCALL_WAIT :
- return syscall_wait(pid);
+ return syscall_wait(p1,p2,p3,pid);
case SYSCALL_WRITE :
- return syscall_write(p1,p2,p3);
+ return syscall_write(p1,p2,p3,pid);
case SYSCALL_GETTIMEOFDAY:
- return syscall_gettimeofday(p1,p2);
+ return syscall_gettimeofday(p1,p2,p3,pid);
case SYSCALL_READDIR :
- return syscall_readdir(p1,p2,p3);
+ return syscall_readdir(p1,p2,p3,pid);
case SYSCALL_KILL :
// return task_kill(p1,p2,p3);
return -1;
case SYSCALL_PIPE :
- return syscall_pipe(p1);
+ return syscall_pipe(p1,p2,p3,pid);
+ case SYSCALL_DUP2 :
+ return syscall_dup2(p1,p2,p3,pid);
}
kpanic("unknown syscall");
}
diff --git a/kernel/syscalls.h b/kernel/syscalls.h
index b7422af..d90e314 100644
--- a/kernel/syscalls.h
+++ b/kernel/syscalls.h
@@ -1,3 +1,17 @@
+/**
+ * @file
+ *
+ * Fool OS - System Call Interface
+ * ===============================
+ *
+ * Most of the syscalls are loosely based on a very small subset of the
+ * linux system calls.
+ *
+ * They seem enough to back a small C Library as newlib in this case.
+ *
+ *
+ */
+
#define SYSCALL_EXIT 60
#define SYSCALL_EXECVE 64
#define SYSCALL_FORK 72
@@ -10,28 +24,32 @@
#define SYSCALL_LINK 82
#define SYSCALL_LSEEK 69
#define SYSCALL_READ 62
-#define SYSCALL_SBRK 70 // linux??
-#define SYSCALL_STAT 74
-#define SYSCALL_FSTAT 67
-#define SYSCALL_LSTAT 79
+#define SYSCALL_SBRK 70
+#define SYSCALL_STAT 74 // need all?
+#define SYSCALL_FSTAT 67 // need all?
+#define SYSCALL_LSTAT 79 // need all?
#define SYSCALL_TIMES 75
#define SYSCALL_UNLINK 76
#define SYSCALL_WAIT 77
#define SYSCALL_WRITE 61
#define SYSCALL_GETTIMEOFDAY 71
-#define SYSCALL_READDIR 63 // getdents?
+#define SYSCALL_READDIR 63 // linux has getdents
#define SYSCALL_KILL 73
-#define SYSCALL_POLL 80 //shit!?
#define SYSCALL_CLONE 83
#define SYSCALL_PIPE 84
-// TODO! SYSCALL_MKNOD?
+#define SYSCALL_DUP2 86
+
+/** Todo move somewhere else and init per process , think how to make thread safe */
+void fd_init_std_streams(uint32_t pid);
+
+/** returns string representation of the syscall from its number */
+char* syscall_get_name(uint32_t num);
-char* syscall_get_name(uint32_t num);
+/** invoke a syscall from kernel */
uint32_t syscall_generic(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid);
-uint32_t syscall_generic_test(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid);
-int syscall_open(char *name, int flags, int mode);
-int syscall_write(int file, char *buf, int len);
+/** test if a specific syscall is ready to be processed */
+uint32_t syscall_generic_test(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid);
// new planned syscalls for graphx
// TODO: split ncurses and our syscalls??