diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/fifo.c | 38 | ||||
| -rw-r--r-- | kernel/fifo.h | 23 | ||||
| -rw-r--r-- | kernel/kernel.c | 17 | ||||
| -rw-r--r-- | kernel/log.c | 1 | ||||
| -rw-r--r-- | kernel/scheduler.c | 20 | ||||
| -rw-r--r-- | kernel/syscalls.c | 273 | ||||
| -rw-r--r-- | kernel/syscalls.h | 40 |
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?? |
