BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / commit / 05ba3b000a223d1abc7eedd7d71b051d08fc4a04

// Related

Nucleus

Barry System call interface 05ba3b0 (3 years, 2 months ago)
diff --git a/kernel/idt.c b/kernel/idt.c
index 3303aa8..0a93c55 100644
--- a/kernel/idt.c
+++ b/kernel/idt.c
@@ -7,9 +7,10 @@
 
 #include <stdint.h>
 #include <string.h>
-#include <nucleus/panic.h>
-#include <nucleus/memory.h>
 #include <nucleus/cpu.h>
+#include <nucleus/memory.h>
+#include <nucleus/panic.h>
+#include <nucleus/task.h>
 #include <io.h>
 #include "desc.h"
 
@@ -212,7 +213,16 @@ __attribute__((interrupt))
 static void
 exc128(struct InterruptFrame *frame)
 {
-	exc_handler(128, frame, 0);
+	uintptr_t esi, *eax;
+	asm volatile(
+		"mov %%esi, %0;"
+		"lea -12(%%ebp), %1;"
+		: "=r" (esi), "=r" (eax));
+	*eax = syscall_handler(*eax, esi);
+
+	/* Send APIC EOI */
+	if (apic)
+		LAPIC(0xB0) = 0;
 }
 
 /* Interrupts */
diff --git a/task/syscall.c b/task/syscall.c
new file mode 100644
index 0000000..40754e3
--- /dev/null
+++ b/task/syscall.c
@@ -0,0 +1,114 @@
+/*
+ * This file implements the system call handler.  It is called by the exc128
+ * handler function and just switches the syscall number into the syscall list
+ * and runs the relevant function.
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/syscall.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <nucleus/cpu.h>
+#include <nucleus/memory.h>
+#include <nucleus/panic.h>
+#include <nucleus/task.h>
+#include <nucleus/vfs.h>
+
+/* Structure for a System Call Entry */
+struct SyscallEntry {
+	int argc;
+	void *function;
+};
+
+/* List of syscalls */
+struct SyscallEntry syscalls[] = {
+	/* Task */
+	[SYSCALL_DBGPRINTF] = { 1, dbgprintf },
+	[SYSCALL_CLONE]     = { 1, clone },
+	[SYSCALL_EXIT]      = { 1, exit },
+	[SYSCALL_GETPID]    = { 0, getpid },
+	[SYSCALL_GETUID]    = { 0, getuid },
+	[SYSCALL_SETUID]    = { 1, setuid },
+	[SYSCALL_GETEUID]   = { 0, geteuid },
+	[SYSCALL_SETEUID]   = { 1, seteuid },
+	[SYSCALL_GETGID]    = { 0, getgid },
+	[SYSCALL_SETGID]    = { 1, setgid },
+	[SYSCALL_GETEGID]   = { 0, getegid },
+	[SYSCALL_SETEGID]   = { 1, setegid },
+	[SYSCALL_EXECVE]    = { 3, execve },
+	[SYSCALL_WAITPID]   = { 3, waitpid },
+//	[SYSCALL_TIME]      = { 1, time },
+//	[SYSCALL_TIMES]     = { 1, times },
+//	[SYSCALL_SLEEP]     = { 1, sleep },
+
+	/* Files */
+	[SYSCALL_OPEN]     = { 3, open },
+	[SYSCALL_CLOSE]    = { 1, close },
+	[SYSCALL_READ]     = { 3, read },
+	[SYSCALL_WRITE]    = { 3, write },
+	[SYSCALL_IOCTL]    = { 3, ioctl },
+	[SYSCALL_LSEEK]    = { 3, lseek },
+//	[SYSCALL_STAT]     = { 2, stat },
+//	[SYSCALL_FSTAT]    = { 2, fstat },
+//	[SYSCALL_GETDENTS] = { 3, getdents },
+//	[SYSCALL_MKDIR]    = { 2, mkdir },
+//	[SYSCALL_RMDIR]    = { 1, rmdir },
+//	[SYSCALL_MKNOD]    = { 3, mknod },
+//	[SYSCALL_RENAME]   = { 2, rename },
+//	[SYSCALL_DUP]      = { 1, dup },
+//	[SYSCALL_DUP2]     = { 2, dup2 },
+//	[SYSCALL_ISATTY]   = { 1, isatty },
+//	[SYSCALL_PIPE]     = { 1, pipe },
+
+	/* File System */
+	[SYSCALL_MOUNT]  = { 5, mount },
+	[SYSCALL_CHDIR]  = { 1, chdir },
+	[SYSCALL_CHROOT] = { 1, chroot },
+	[SYSCALL_GETCWD] = { 2, getcwd },
+
+	/* Memory */
+	[SYSCALL_MMAP] = { 6, mmap },
+
+	/* Signals */
+	[SYSCALL_TGKILL]      = { 3, tgkill },
+	[SYSCALL_KILL]        = { 2, kill },
+	[SYSCALL_SIGNAL]      = { 2, signal },
+	[SYSCALL_SIGPROCMASK] = { 3, sigprocmask },
+};
+
+/* Handle a syscall */
+int
+syscall_handler(int num, uintptr_t args)
+{
+	int ret = -EINVAL;
+	current->inSyscall = 1;
+
+	/* Find syscall entry */
+	if (num >= sizeof(syscalls) / sizeof(syscalls[0]))
+		goto end;
+	struct SyscallEntry *syscall = &syscalls[num];
+	if (!syscall->function)
+		goto end;
+
+	/* Copy arguments onto stack */
+	if (syscall->argc) {
+		int *val = (int *) args;
+		int argc = syscall->argc;
+		if (!verify_access(val, argc * sizeof(int), PROT_READ))
+			goto end;
+		while (argc--)
+			asm volatile("pushl %0" :: "r" (val[argc]));
+	}
+
+	/* Call function */
+	asm volatile("call *%1" : "=a" (ret) : "r" (syscall->function));
+
+end:
+	current->inSyscall = 0;
+	return ret;
+}