diff options
-rw-r--r-- | pk/file.c | 40 | ||||
-rw-r--r-- | pk/file.h | 1 | ||||
-rw-r--r-- | pk/frontend.c | 3 | ||||
-rw-r--r-- | pk/frontend.h | 2 | ||||
-rw-r--r-- | pk/init.c | 2 | ||||
-rw-r--r-- | pk/syscall.c | 148 | ||||
-rw-r--r-- | pk/syscall.h | 42 |
7 files changed, 218 insertions, 20 deletions
@@ -7,9 +7,9 @@ #include "frontend.h" #include "vm.h" -#define MAX_FDS 32 +#define MAX_FDS 64 static atomic_t fds[MAX_FDS]; -#define MAX_FILES 32 +#define MAX_FILES 64 static file_t files[MAX_FILES] = {[0 ... MAX_FILES-1] = {-1,{0}}}; file_t *stdout, *stdin, *stderr; @@ -26,7 +26,7 @@ void file_decref(file_t* f) mb(); atomic_set(&f->refcnt, 0); - frontend_syscall(SYS_close, kfd, 0, 0, 0); + frontend_syscall(SYS_close, kfd, 0, 0, 0, 0); } } @@ -90,7 +90,27 @@ file_t* file_open(const char* fn, int flags, int mode) return ERR_PTR(-ENOMEM); size_t fn_size = strlen(fn)+1; - long ret = frontend_syscall(SYS_open, (long)fn, fn_size, flags, mode); + long ret = frontend_syscall(SYS_open, (long)fn, fn_size, flags, mode, 0); + if (ret >= 0) + { + f->kfd = ret; + return f; + } + else + { + file_decref(f); + return ERR_PTR(ret); + } +} + +file_t* file_openat(int dirfd, const char* fn, int flags, int mode) +{ + file_t* f = file_get_free(); + if (f == NULL) + return ERR_PTR(-ENOMEM); + + size_t fn_size = strlen(fn)+1; + long ret = frontend_syscall(SYS_openat, dirfd, (long)fn, fn_size, flags, mode); if (ret >= 0) { f->kfd = ret; @@ -119,34 +139,34 @@ int fd_close(int fd) ssize_t file_read(file_t* f, void* buf, size_t size) { populate_mapping(buf, size, PROT_WRITE); - return frontend_syscall(SYS_read, f->kfd, (uintptr_t)buf, size, 0); + return frontend_syscall(SYS_read, f->kfd, (uintptr_t)buf, size, 0, 0); } ssize_t file_pread(file_t* f, void* buf, size_t size, off_t offset) { populate_mapping(buf, size, PROT_WRITE); - return frontend_syscall(SYS_pread, f->kfd, (uintptr_t)buf, size, offset); + return frontend_syscall(SYS_pread, f->kfd, (uintptr_t)buf, size, offset, 0); } ssize_t file_write(file_t* f, const void* buf, size_t size) { populate_mapping(buf, size, PROT_READ); - return frontend_syscall(SYS_write, f->kfd, (uintptr_t)buf, size, 0); + return frontend_syscall(SYS_write, f->kfd, (uintptr_t)buf, size, 0, 0); } ssize_t file_pwrite(file_t* f, const void* buf, size_t size, off_t offset) { populate_mapping(buf, size, PROT_READ); - return frontend_syscall(SYS_pwrite, f->kfd, (uintptr_t)buf, size, offset); + return frontend_syscall(SYS_pwrite, f->kfd, (uintptr_t)buf, size, offset, 0); } int file_stat(file_t* f, struct stat* s) { populate_mapping(s, sizeof(*s), PROT_WRITE); - return frontend_syscall(SYS_fstat, f->kfd, (uintptr_t)s, 0, 0); + return frontend_syscall(SYS_fstat, f->kfd, (uintptr_t)s, 0, 0, 0); } ssize_t file_lseek(file_t* f, size_t ptr, int dir) { - return frontend_syscall(SYS_lseek, f->kfd, ptr, dir, 0); + return frontend_syscall(SYS_lseek, f->kfd, ptr, dir, 0, 0); } @@ -21,6 +21,7 @@ void file_decref(file_t*); void file_incref(file_t*); int file_dup(file_t*); +file_t* file_openat(int dirfd, const char* fn, int flags, int mode); ssize_t file_pwrite(file_t* f, const void* buf, size_t n, off_t off); ssize_t file_pread(file_t* f, void* buf, size_t n, off_t off); ssize_t file_write(file_t* f, const void* buf, size_t n); diff --git a/pk/frontend.c b/pk/frontend.c index 77d71a6..4c6051e 100644 --- a/pk/frontend.c +++ b/pk/frontend.c @@ -5,7 +5,7 @@ #include "frontend.h" #include <stdint.h> -long frontend_syscall(long n, long a0, long a1, long a2, long a3) +long frontend_syscall(long n, long a0, long a1, long a2, long a3, long a4) { static volatile uint64_t magic_mem[8]; @@ -17,6 +17,7 @@ long frontend_syscall(long n, long a0, long a1, long a2, long a3) magic_mem[2] = a1; magic_mem[3] = a2; magic_mem[4] = a3; + magic_mem[5] = a4; mb(); diff --git a/pk/frontend.h b/pk/frontend.h index 9610234..edbf22a 100644 --- a/pk/frontend.h +++ b/pk/frontend.h @@ -3,6 +3,6 @@ #ifndef _RISCV_FRONTEND_H #define _RISCV_FRONTEND_H -long frontend_syscall(long n, long a0, long a1, long a2, long a3); +long frontend_syscall(long n, long a0, long a1, long a2, long a3, long a4); #endif @@ -54,7 +54,7 @@ static void user_init() size_t stack_top = current.stack_top; struct args* args = (struct args*)(stack_top - argc_argv_size); populate_mapping(args, argc_argv_size, PROT_WRITE); - long r = frontend_syscall(SYS_getmainvars, (long)args, argc_argv_size, 0, 0); + long r = frontend_syscall(SYS_getmainvars, (long)args, argc_argv_size, 0, 0, 0); kassert(r == 0); // argv[0] is the proxy kernel itself. skip it and any flags. diff --git a/pk/syscall.c b/pk/syscall.c index 6d58be0..e25b883 100644 --- a/pk/syscall.c +++ b/pk/syscall.c @@ -7,6 +7,7 @@ #include "vm.h" #include <string.h> #include <errno.h> +//#include <fcntl.h> typedef long (*syscall_t)(long, long, long, long, long, long, long); @@ -26,7 +27,7 @@ void sys_exit(int code) if (current.t0) printk("%ld cycles\n", rdcycle() - current.t0); - frontend_syscall(SYS_exit, code, 0, 0, 0); + frontend_syscall(SYS_exit, code, 0, 0, 0, 0); while (1); } @@ -44,6 +45,20 @@ ssize_t sys_read(int fd, char* buf, size_t n) return r; } +ssize_t sys_pread(int fd, char* buf, size_t n, off_t offset) +{ + ssize_t r = -EBADF; + file_t* f = file_get(fd); + + if (f) + { + r = file_pread(f, buf, n, offset); + file_decref(f); + } + + return r; +} + ssize_t sys_write(int fd, const char* buf, size_t n) { ssize_t r = -EBADF; @@ -60,6 +75,7 @@ ssize_t sys_write(int fd, const char* buf, size_t n) int sys_open(const char* name, int flags, int mode) { + printk("OPEN(%s)\n",name); file_t* file = file_open(name, flags, mode); if (IS_ERR_VALUE(file)) return PTR_ERR(file); @@ -71,8 +87,30 @@ int sys_open(const char* name, int flags, int mode) return fd; } +int sys_openat(int dirfd, const char* name, int flags, int mode) +{ + if(name[0] == '/'){ + return sys_open(name, flags, mode); + } + file_t* dir = file_get(dirfd); + if(dir) + { + file_t* file = file_openat(dir->kfd, name, flags, mode); + if (IS_ERR_VALUE(file)) + return PTR_ERR(file); + + int fd = file_dup(file); + if (fd < 0) + return -ENOMEM; + + return fd; + } + return -EBADF; +} + int sys_close(int fd) { + //printk("CLOSE(%ld)\n",fd); int ret = fd_close(fd); if (ret < 0) return -EBADF; @@ -81,6 +119,7 @@ int sys_close(int fd) int sys_fstat(int fd, void* st) { + printk("FSTAT(%ld)\n",fd); int r = -EBADF; file_t* f = file_get(fd); @@ -93,6 +132,34 @@ int sys_fstat(int fd, void* st) return r; } +int sys_fcntl(int fd, int cmd, int arg) +{ + int r = -EBADF; + file_t* f = file_get(fd); + + if (f) + { + r = frontend_syscall(SYS_fcntl, f->kfd, cmd, arg, 0, 0); + file_decref(f); + } + + return r; +} + +int sys_dup(int fd) +{ + int r = -EBADF; + file_t* f = file_get(fd); + + if (f) + { + r = file_dup(f); + file_decref(f); + } + + return r; +} + ssize_t sys_lseek(int fd, size_t ptr, int dir) { ssize_t r = -EBADF; @@ -111,14 +178,46 @@ long sys_stat(const char* name, void* st) { size_t name_size = strlen(name)+1; populate_mapping(st, sizeof(struct stat), PROT_WRITE); - return frontend_syscall(SYS_stat, (uintptr_t)name, name_size, (uintptr_t)st, 0); + return frontend_syscall(SYS_stat, (uintptr_t)name, name_size, (uintptr_t)st, 0, 0); } long sys_lstat(const char* name, void* st) { size_t name_size = strlen(name)+1; populate_mapping(st, sizeof(struct stat), PROT_WRITE); - return frontend_syscall(SYS_lstat, (uintptr_t)name, name_size, (uintptr_t)st, 0); + return frontend_syscall(SYS_lstat, (uintptr_t)name, name_size, (uintptr_t)st, 0, 0); +} +long sys_fstatat(int dirfd, const char* name, void* st, int flags) +{ + if(name[0] == '/'){ + return sys_stat(name, st); + } + file_t* dir = file_get(dirfd); + if(dir) + { + size_t name_size = strlen(name)+1; + populate_mapping(st, sizeof(struct stat), PROT_WRITE); + return frontend_syscall(SYS_fstatat, dir->kfd, (uintptr_t)name, name_size, (uintptr_t)st, flags); + } + return -EBADF; +} + +int sys_access(const char *name, int mode){ + size_t name_size = strlen(name)+1; + return frontend_syscall(SYS_access, (uintptr_t)name, name_size, mode, 0, 0); +} + +int sys_faccessat(int dirfd, const char *name, int mode, int flags){ + if(name[0] == '/'){ + return sys_access(name, mode); + } + file_t* dir = file_get(dirfd); + if(dir) + { + size_t name_size = strlen(name)+1; + return frontend_syscall(SYS_access, dir->kfd, (uintptr_t)name, name_size, mode, flags); + } + return -EBADF; } long sys_link(const char* old_name, const char* new_name) @@ -126,13 +225,25 @@ long sys_link(const char* old_name, const char* new_name) size_t old_size = strlen(old_name)+1; size_t new_size = strlen(new_name)+1; return frontend_syscall(SYS_link, (uintptr_t)old_name, old_size, - (uintptr_t)new_name, new_size); + (uintptr_t)new_name, new_size, 0); } long sys_unlink(const char* name, size_t len) { size_t name_size = strlen(name)+1; - return frontend_syscall(SYS_unlink, (uintptr_t)name, name_size, 0, 0); + return frontend_syscall(SYS_unlink, (uintptr_t)name, name_size, 0, 0, 0); +} + +long sys_mkdir(const char* name, int mode) +{ + size_t name_size = strlen(name)+1; + return frontend_syscall(SYS_mkdir, (uintptr_t)name, name_size, mode, 0, 0); +} + +long sys_getcwd(const char* buf, size_t size) +{ + populate_mapping(buf, size, PROT_WRITE); + return frontend_syscall(SYS_getcwd, (uintptr_t)buf, size, 0, 0, 0); } size_t sys_brk(size_t pos) @@ -152,6 +263,11 @@ int sys_uname(void* buf) return 0; } +pid_t sys_getpid() +{ + return 0; +} + int sys_getuid() { return 0; @@ -159,7 +275,10 @@ int sys_getuid() uintptr_t sys_mmap(uintptr_t addr, size_t length, int prot, int flags, int fd, off_t offset) { - return do_mmap(addr, length, prot, flags, fd, offset); + printk("MMAP(ad:%ld,len:%ld,prot:%ld,flags:%ld,fd:%ld,off:%ld\n",addr,length,prot,flags,fd,offset); + uintptr_t ret = do_mmap(addr, length, prot, flags, fd, offset); + //printk("MMAP DONE\n"); + return ret; } int sys_munmap(uintptr_t addr, size_t length) @@ -235,23 +354,35 @@ ssize_t sys_writev(int fd, const void* iov, int cnt) return ret; } + +int sys_getdents(int fd, void* dirbuf, int count) +{ + return 0; //stub +} + long syscall(long a0, long a1, long a2, long a3, long a4, long a5, long n) { const static void* syscall_table[] = { [SYS_exit] = sys_exit, [SYS_exit_group] = sys_exit, [SYS_read] = sys_read, + [SYS_pread] = sys_pread, [SYS_write] = sys_write, [SYS_open] = sys_open, + [SYS_openat] = sys_openat, [SYS_close] = sys_close, [SYS_fstat] = sys_fstat, [SYS_lseek] = sys_lseek, [SYS_stat] = sys_stat, [SYS_lstat] = sys_lstat, + [SYS_fstatat] = sys_fstatat, [SYS_link] = sys_link, [SYS_unlink] = sys_unlink, + [SYS_mkdir] = sys_mkdir, + [SYS_getcwd] = sys_getcwd, [SYS_brk] = sys_brk, [SYS_uname] = sys_uname, + [SYS_getpid] = sys_getpid, [SYS_getuid] = sys_getuid, [SYS_geteuid] = sys_getuid, [SYS_getgid] = sys_getuid, @@ -264,6 +395,11 @@ long syscall(long a0, long a1, long a2, long a3, long a4, long a5, long n) [SYS_gettimeofday] = sys_gettimeofday, [SYS_times] = sys_times, [SYS_writev] = sys_writev, + [SYS_access] = sys_access, + [SYS_faccessat] = sys_faccessat, + [SYS_fcntl] = sys_fcntl, + [SYS_getdents] = sys_getdents, + [SYS_dup] = sys_dup, }; if(n >= ARRAY_SIZE(syscall_table) || !syscall_table[n]) diff --git a/pk/syscall.h b/pk/syscall.h index fcb3423..e3a88ce 100644 --- a/pk/syscall.h +++ b/pk/syscall.h @@ -3,7 +3,47 @@ #ifndef _PK_SYSCALL_H #define _PK_SYSCALL_H -#include <machine/syscall.h> +#define SYS_exit 93 +#define SYS_exit_group 94 +#define SYS_getpid 172 +#define SYS_kill 129 +#define SYS_read 63 +#define SYS_write 64 +#define SYS_open 1024 +#define SYS_openat 56 +#define SYS_close 57 +#define SYS_lseek 62 +#define SYS_brk 214 +#define SYS_link 1025 +#define SYS_unlink 1026 +#define SYS_mkdir 1030 +#define SYS_chdir 49 +#define SYS_getcwd 17 +#define SYS_stat 1038 +#define SYS_fstat 80 +#define SYS_lstat 1039 +#define SYS_fstatat 79 +#define SYS_access 1033 +#define SYS_faccessat 48 +#define SYS_pread 67 +#define SYS_pwrite 68 +#define SYS_uname 160 +#define SYS_getuid 174 +#define SYS_geteuid 175 +#define SYS_getgid 176 +#define SYS_getegid 177 +#define SYS_mmap 222 +#define SYS_munmap 215 +#define SYS_mremap 216 +#define SYS_time 1062 +#define SYS_getmainvars 2011 +#define SYS_rt_sigaction 134 +#define SYS_writev 66 +#define SYS_gettimeofday 169 +#define SYS_times 153 +#define SYS_fcntl 25 +#define SYS_getdents 61 +#define SYS_dup 23 #define IS_ERR_VALUE(x) ((unsigned long)(x) >= (unsigned long)-4096) #define ERR_PTR(x) ((void*)(long)(x)) |