Implementing and testing a few system calls
This commit is contained in:
parent
49c8d7ba48
commit
2611795d6f
15
include/syscall.h
Normal file
15
include/syscall.h
Normal 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
8
include/unistd.h
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
#ifndef __UNISTD_H__
|
||||
#define __UNISTD_H__
|
||||
|
||||
int syscall(int number, ...);
|
||||
|
||||
#endif /* __UNISTD_H__ */
|
||||
|
@ -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
13
lib/libc/amd64/syscall.S
Normal file
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* System Call
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
|
||||
.text
|
||||
|
||||
FUNC_BEGIN(syscall)
|
||||
int $60
|
||||
ret
|
||||
FUNC_END(syscall)
|
||||
|
@ -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
46
lib/libc/syscall.c
Normal 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);
|
||||
}
|
||||
|
@ -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',
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user