Implementing and testing a few system calls

This commit is contained in:
Ali Mashtizadeh 2014-08-07 17:58:41 -07:00
parent 49c8d7ba48
commit 2611795d6f
12 changed files with 176 additions and 15 deletions

15
include/syscall.h Normal file
View File

@ -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__ */

8
include/unistd.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef __UNISTD_H__
#define __UNISTD_H__
int syscall(int number, ...);
#endif /* __UNISTD_H__ */

View File

@ -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'])

13
lib/libc/amd64/syscall.S Normal file
View File

@ -0,0 +1,13 @@
/*
* System Call
*/
#include <machine/asm.h>
.text
FUNC_BEGIN(syscall)
int $60
ret
FUNC_END(syscall)

View File

@ -1,6 +1,9 @@
#include <stdint.h>
#include <stdlib.h>
#include <syscall.h>
int
atexit(void (*function)(void))
{
@ -11,6 +14,8 @@ exit(int status)
{
//
SystemExit(status);
__builtin_unreachable();
}

46
lib/libc/syscall.c Normal file
View File

@ -0,0 +1,46 @@
#include <stdbool.h>
#include <stdint.h>
#include <sys/syscall.h>
#include <syscall.h>
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);
}

View File

@ -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',

View File

@ -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)
{

View File

@ -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();

View File

@ -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;

View File

@ -3,6 +3,8 @@
#include <stdint.h>
#include <sys/kassert.h>
#include <sys/kmem.h>
#include <sys/thread.h>
#include <sys/syscall.h>
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:

View File

@ -14,12 +14,15 @@
#include <machine/pmap.h>
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);