Orion
Barry Importing existing Orion kernel d41a53c (2 years, 4 months ago)diff --git a/task/syscall.c b/task/syscall.c new file mode 100644 index 0000000..d43542d --- /dev/null +++ b/task/syscall.c @@ -0,0 +1,96 @@ +/* + * This file handles system calls. Every system call gets passed to the + * syscall_handler() function, which decides which Kernel function to run. + * There is an array of syscalls, which are indexed numerically, these are the + * syscall numbers. + */ + +#include <sys/syscall.h> +#include <sys/mman.h> +#include <errno.h> +#include "task.h" +#include "../screen.h" + +/* List of syscalls */ +void *syscalls[] = { + /* Tasking */ + [SYSCALL_DBGPRINTF] = dbgprintf, + [SYSCALL_CLONE] = clone, + [SYSCALL_EXIT] = exit, + [SYSCALL_GETPID] = getpid, + [SYSCALL_GETUID] = getuid, + [SYSCALL_SETUID] = setuid, + [SYSCALL_GETEUID] = geteuid, + [SYSCALL_SETEUID] = seteuid, + [SYSCALL_GETGID] = getgid, + [SYSCALL_SETGID] = setgid, + [SYSCALL_GETEGID] = getegid, + [SYSCALL_SETEGID] = setegid, + [SYSCALL_EXECVE] = execve, + [SYSCALL_WAITPID] = waitpid, + [SYSCALL_TGKILL] = tgkill, + [SYSCALL_KILL] = kill, + [SYSCALL_TIME] = time, + [SYSCALL_TIMES] = times, + [SYSCALL_SLEEP] = sleep, + + /* Files */ + [SYSCALL_OPEN] = open, + [SYSCALL_CLOSE] = close, + [SYSCALL_READ] = read, + [SYSCALL_WRITE] = write, + [SYSCALL_IOCTL] = ioctl, + [SYSCALL_LSEEK] = lseek, + [SYSCALL_STAT] = stat, + [SYSCALL_GETDENTS] = getdents, + [SYSCALL_MKDIR] = mkdir, + [SYSCALL_RMDIR] = rmdir, + [SYSCALL_MKNOD] = mknod, + [SYSCALL_RENAME] = rename, + [SYSCALL_DUP] = dup, + [SYSCALL_DUP2] = dup2, + [SYSCALL_ISATTY] = isatty, + + /* File System */ + [SYSCALL_MOUNT] = mount, + [SYSCALL_CHDIR] = chdir, + [SYSCALL_CHROOT] = chroot, + [SYSCALL_GETCWD] = getcwd, + + /* Memory */ + [SYSCALL_MMAP] = mmap, + + /* Messaging */ + [SYSCALL_NB_SEND_MSG] = nb_send_msg, + [SYSCALL_SEND_MSG] = send_msg, + [SYSCALL_NB_RECV_MSG] = nb_recv_msg, + [SYSCALL_RECV_MSG] = recv_msg, +}; + +/* Handle a syscall */ +void +syscall_handler(InterruptFrame *frame) +{ + if (frame->eax >= sizeof(syscalls)/sizeof(syscalls[0])) { + frame->eax = -EINVAL; + return; + } + void *handler = syscalls[frame->eax]; + int ret; + current->inSyscall = 1; + + size_t num; + int *val = (int *) frame->esi; + if (!verify_access(val, frame->ecx * sizeof(int), PROT_READ)) { + frame->eax = -EINVAL; + return; + } + /* Push args onto stack */ + for (num = frame->ecx; num; num--) + asm volatile("pushl %0" :: "r" (val[num - 1])); + /* Call handler */ + asm volatile("call *%1" : "=a" (ret) : "r" (handler)); + + frame->eax = ret; + current->inSyscall = 0; +}