From 2611795d6f055cb0b119b8756ab82f132b34a530 Mon Sep 17 00:00:00 2001 From: Ali Mashtizadeh Date: Thu, 7 Aug 2014 17:58:41 -0700 Subject: [PATCH] Implementing and testing a few system calls --- include/syscall.h | 15 ++++++++++++ include/unistd.h | 8 +++++++ lib/libc/SConscript | 9 +++++++- lib/libc/amd64/syscall.S | 13 +++++++++++ lib/libc/exit.c | 5 ++++ lib/libc/syscall.c | 46 +++++++++++++++++++++++++++++++++++++ sys/SConscript | 2 +- sys/amd64/pmap.c | 20 ++++++++++++++++ sys/include/thread.h | 2 ++ sys/kern/loader.c | 1 - sys/kern/syscall.c | 49 ++++++++++++++++++++++++++++++++-------- sys/kern/thread.c | 21 +++++++++++++++-- 12 files changed, 176 insertions(+), 15 deletions(-) create mode 100644 include/syscall.h create mode 100644 include/unistd.h create mode 100644 lib/libc/amd64/syscall.S create mode 100644 lib/libc/syscall.c diff --git a/include/syscall.h b/include/syscall.h new file mode 100644 index 0000000..eae3690 --- /dev/null +++ b/include/syscall.h @@ -0,0 +1,15 @@ + +#ifndef __SYSCALL_H__ +#define __SYSCALL_H__ + +uint64_t SystemTime(); +void SystemExit(int status); +uint64_t SystemGetPID(); + +// Memory +void *SystemMemMap(void *addr, uint64_t len, int flags); +int SystemMemUnmap(void *addr, uint64_t len); +int SystemMemProtect(void *addr, uint64_t len, int flags); + +#endif /* __SYSCALL_H__ */ + diff --git a/include/unistd.h b/include/unistd.h new file mode 100644 index 0000000..d608ad4 --- /dev/null +++ b/include/unistd.h @@ -0,0 +1,8 @@ + +#ifndef __UNISTD_H__ +#define __UNISTD_H__ + +int syscall(int number, ...); + +#endif /* __UNISTD_H__ */ + diff --git a/lib/libc/SConscript b/lib/libc/SConscript index 3e0f433..198351f 100644 --- a/lib/libc/SConscript +++ b/lib/libc/SConscript @@ -7,9 +7,16 @@ libc_env = env.Clone() src = [ ] src_common = [ - "exit.c" + "exit.c", + "syscall.c", ] +src_amd64 = [ + "amd64/syscall.S" +] + +if (env["ARCH"] == "amd64"): + src.append(src_amd64) src.append(src_common) libc_env.Append(CPPFLAGS = ['-nostdinc']) diff --git a/lib/libc/amd64/syscall.S b/lib/libc/amd64/syscall.S new file mode 100644 index 0000000..8f696ae --- /dev/null +++ b/lib/libc/amd64/syscall.S @@ -0,0 +1,13 @@ +/* + * System Call + */ + +#include + +.text + +FUNC_BEGIN(syscall) + int $60 + ret +FUNC_END(syscall) + diff --git a/lib/libc/exit.c b/lib/libc/exit.c index 3614d11..8342775 100644 --- a/lib/libc/exit.c +++ b/lib/libc/exit.c @@ -1,6 +1,9 @@ +#include #include +#include + int atexit(void (*function)(void)) { @@ -11,6 +14,8 @@ exit(int status) { // + SystemExit(status); + __builtin_unreachable(); } diff --git a/lib/libc/syscall.c b/lib/libc/syscall.c new file mode 100644 index 0000000..455098e --- /dev/null +++ b/lib/libc/syscall.c @@ -0,0 +1,46 @@ + +#include +#include + +#include +#include + +uint64_t syscall(int num, ...); + +uint64_t +SystemTime() +{ + return syscall(SYSCALL_TIME); +} + +void +SystemExit(int status) +{ + syscall(SYSCALL_EXIT); +} + +uint64_t +SystemGetPID() +{ + return syscall(SYSCALL_GETPID); +} + +void * +SystemMemMap(void *addr, uint64_t len, int flags) +{ + return (void *)syscall(SYSCALL_MMAP, addr, len, flags); +} + +int +SystemMemUnmap(void *addr, uint64_t len) +{ + return syscall(SYSCALL_MUNMAP, addr, len); +} + + +int +SystemMemProtect(void *addr, uint64_t len, int flags) +{ + return syscall(SYSCALL_MPROTECT, addr, len, flags); +} + diff --git a/sys/SConscript b/sys/SConscript index 32c0f41..1f155a8 100644 --- a/sys/SConscript +++ b/sys/SConscript @@ -54,8 +54,8 @@ src_common = [ if (env["ARCH"] == "amd64"): src.append(src_amd64) - src.append(src_common) ldscript = "#sys/amd64/kernel.lds" +src.append(src_common) kern_env.Append(LINKFLAGS = ['-T', ldscript[1:], '-N', '-nostdlib']) kern_env.Append(CPPFLAGS = ['-ffreestanding', '-fno-builtin', '-nostdinc', diff --git a/sys/amd64/pmap.c b/sys/amd64/pmap.c index 7e96524..d47d6bb 100644 --- a/sys/amd64/pmap.c +++ b/sys/amd64/pmap.c @@ -219,6 +219,26 @@ PMap_Map(AS *as, uint64_t phys, uint64_t virt, uint64_t pages, uint64_t flags) return true; } +bool +PMap_Unmap(AS *as, uint64_t va, uint64_t pages) +{ + int i; + PageEntry *entry; + + for (i = 0; i < pages; i++) { + uint64_t va = va + PGSIZE * i; + PMapLookupEntry(as, va, &entry, PGSIZE); + if (!entry) { + kprintf("Unmap tried to allocate memory!\n"); + return false; + } + + *entry = 0; + } + + return true; +} + void PMap_SystemLookup(uint64_t va, PageEntry **entry, int size) { diff --git a/sys/include/thread.h b/sys/include/thread.h index e9d2c4d..03197ab 100644 --- a/sys/include/thread.h +++ b/sys/include/thread.h @@ -20,6 +20,7 @@ typedef struct Thread { ThreadArch arch; AS *space; uintptr_t kstack; + uint64_t tid; // Scheduler int schedState; TAILQ_ENTRY(Thread) schedQueue; @@ -35,6 +36,7 @@ Thread *Thread_Current(); Thread *Thread_Create(); Thread *Thread_KThreadCreate(void (*f)(void*), void *arg); void Thread_SetRunnable(Thread *thr); +void Thread_SetZombie(Thread *thr); void Thread_Destroy(Thread *thr); void Thread_Switch(Thread *oldthr, Thread *newthr); void Thread_Scheduler(); diff --git a/sys/kern/loader.c b/sys/kern/loader.c index 0092687..6f38d42 100644 --- a/sys/kern/loader.c +++ b/sys/kern/loader.c @@ -74,7 +74,6 @@ Loader_Load(Thread *thr, void *buf, uint64_t len) tf.rsp = 0x70000000 + PGSIZE; tf.ss = SEL_UDS | 3; tf.rflags = RFLAGS_IF; - Trap_Dump(&tf); Trap_Pop(&tf); return true; diff --git a/sys/kern/syscall.c b/sys/kern/syscall.c index 9e400c7..33e69c2 100644 --- a/sys/kern/syscall.c +++ b/sys/kern/syscall.c @@ -3,6 +3,8 @@ #include #include +#include +#include #include uint64_t @@ -12,44 +14,70 @@ Syscall_Time() return 0; } -uint64_t +void Syscall_Exit(uint64_t status) { - NOT_IMPLEMENTED(); - return 0; + Thread *cur = Thread_Current(); + + Thread_SetZombie(cur); + Thread_Scheduler(); + + // Should not return + Panic("Returned to exited thread!\n"); + + return; } uint64_t Syscall_Spawn(uint64_t path) { - NOT_IMPLEMENTED(); + //Thread *thr = Thread_Create(); + return 0; } uint64_t Syscall_GetPID() { - NOT_IMPLEMENTED(); - return 0; + Thread *cur = Thread_Current(); + return cur->tid; } uint64_t Syscall_MMap(uint64_t addr, uint64_t len, uint64_t prot) { - NOT_IMPLEMENTED(); - return 0; + Thread *cur = Thread_Current(); + uint64_t p; + + for (p = 0; p < len; p += PGSIZE) + { + void *pg = PAlloc_AllocPage(); + PMap_Map(cur->space, (uint64_t)DMVA2PA(pg), addr + p, 1, 0); + } + + return addr; } uint64_t Syscall_MUnmap(uint64_t addr, uint64_t len) { - NOT_IMPLEMENTED(); + Thread *cur = Thread_Current(); + uint64_t p; + + for (p = 0; p < len; p += PGSIZE) + { + // Free page + } + + PMap_Unmap(cur->space, addr, len /= PGSIZE); + return 0; } uint64_t Syscall_MProtect(uint64_t addr, uint64_t len, uint64_t prot) { + Thread *cur = Thread_Current(); NOT_IMPLEMENTED(); return 0; } @@ -79,7 +107,8 @@ Syscall_Entry(uint64_t syscall, uint64_t a1, uint64_t a2, case SYSCALL_TIME: return Syscall_Time(); case SYSCALL_EXIT: - return Syscall_Exit(a1); + Syscall_Exit(a1); + break; case SYSCALL_MMAP: return Syscall_MMap(a1, a2, a3); case SYSCALL_MUNMAP: diff --git a/sys/kern/thread.c b/sys/kern/thread.c index 262e346..fe0b803 100644 --- a/sys/kern/thread.c +++ b/sys/kern/thread.c @@ -14,12 +14,15 @@ #include Spinlock threadLock; +uint64_t nextThreadID; Thread *curProc; TAILQ_HEAD(ThreadQueueHead, Thread) threadQueue; void Thread_Init() { + nextThreadID = 1; + // Create an thread object for current context curProc = Thread_Create(); curProc->schedState = SCHED_STATE_RUNNING; @@ -45,6 +48,7 @@ Thread_Create() memset(thr, 0, sizeof(*thr)); + thr->tid = nextThreadID++; thr->kstack = (uintptr_t)PAlloc_AllocPage(); if (thr->kstack == 0) { PAlloc_FreePage(thr); @@ -89,6 +93,17 @@ Thread_SetRunnable(Thread *thr) Spinlock_Unlock(&threadLock); } +void +Thread_SetZombie(Thread *thr) +{ + Spinlock_Lock(&threadLock); + + thr->schedState = SCHED_STATE_ZOMBIE; + // XXX: Add to wait queue + + Spinlock_Unlock(&threadLock); +} + void Thread_Destroy(Thread *thr) { @@ -122,11 +137,13 @@ Thread_Scheduler() prev = curProc; curProc = next; - prev->schedState = SCHED_STATE_RUNNABLE; next->schedState = SCHED_STATE_RUNNING; next->ctxSwitches++; - TAILQ_INSERT_TAIL(&threadQueue, prev, schedQueue); + if (prev->schedState == SCHED_STATE_RUNNING) { + prev->schedState = SCHED_STATE_RUNNABLE; + TAILQ_INSERT_TAIL(&threadQueue, prev, schedQueue); + } Thread_Switch(prev, next);