summaryrefslogtreecommitdiffstats
path: root/usr
diff options
context:
space:
mode:
Diffstat (limited to 'usr')
-rw-r--r--usr/elf.h12
-rw-r--r--usr/syscall.c23
-rw-r--r--usr/syscall.d2
-rw-r--r--usr/syscall.h10
-rw-r--r--usr/umode.c31
-rw-r--r--usr/umode.d3
-rw-r--r--usr/umode.h8
7 files changed, 89 insertions, 0 deletions
diff --git a/usr/elf.h b/usr/elf.h
new file mode 100644
index 0000000..d805e55
--- /dev/null
+++ b/usr/elf.h
@@ -0,0 +1,12 @@
+#ifndef JOVE_USER_ELF_H
+#define JOVE_USER_ELF_H 1
+
+#include <stddef.h>
+
+/**Load an ELF file into usermode memory.
+ * @param data pointer to ELF file data buffer
+ * @param len length of ELF file data buffer
+ * @return entry point for loaded ELF exec*/
+void *elf_load(const void *data, size_t len);
+
+#endif
diff --git a/usr/syscall.c b/usr/syscall.c
new file mode 100644
index 0000000..0ea5700
--- /dev/null
+++ b/usr/syscall.c
@@ -0,0 +1,23 @@
+#include "syscall.h"
+#include "mem/memory.h"
+#include "io/log.h"
+
+int _syscall_handler_log(struct syscall_log *req)
+{
+ klogf("Message ptr %#016X\n", req->message);
+ if(!mem_check_ptr(req->message)) return -1;
+ klogf("%s", req->message);
+ return 0;
+}
+
+void *_syscall_handlers[SYSCALL_COUNT] = {
+ _syscall_handler_log
+};
+
+int
+syscall_handler(syscall_t *req)
+{
+ if(!mem_check_ptr(req)) return -1;
+ if(req->id >= SYSCALL_COUNT) return -1;
+ return ((syscall_handler_t)(_syscall_handlers[req->id]))(req);
+}
diff --git a/usr/syscall.d b/usr/syscall.d
new file mode 100644
index 0000000..9d5acbf
--- /dev/null
+++ b/usr/syscall.d
@@ -0,0 +1,2 @@
+usr/syscall.o: usr/syscall.c usr/syscall.h abi/syscall.h mem/memory.h \
+ mem/slab.h io/log.h
diff --git a/usr/syscall.h b/usr/syscall.h
new file mode 100644
index 0000000..49beb85
--- /dev/null
+++ b/usr/syscall.h
@@ -0,0 +1,10 @@
+#ifndef JOVE_USER_SYSCALL_H
+#define JOVE_USER_SYSCALL_H 1
+
+#include "abi/syscall.h"
+
+typedef int (*syscall_handler_t)(syscall_t*);
+
+int _syscall_handler_log(struct syscall_log *req);
+
+#endif
diff --git a/usr/umode.c b/usr/umode.c
new file mode 100644
index 0000000..4ef5306
--- /dev/null
+++ b/usr/umode.c
@@ -0,0 +1,31 @@
+#include "umode.h"
+#include "elf.h"
+#include "boot/cmdline.h"
+#include "lib/jove.h"
+#include "ird/initrd.h"
+#include "mem/memory.h"
+
+void
+umode_setup(void)
+{
+ extern void syscall_setup_syscall(void);
+ syscall_setup_syscall();
+
+ const char *init_path = cmdline_get("init");
+ if(init_path == NULL)
+ kpanic("Missing path to init ELF file / binary\n");
+
+ struct InitrdFile *init_file = ird_getfile(init_path);
+ if(init_file == NULL)
+ kpanic("Missing init file %s in initrd\n", init_path);
+
+ void (*entry_point)(void) = elf_load(init_file->data, init_file->size);
+ if(entry_point == NULL)
+ kpanic("Init file %s is incorrectly formatted (want ELF64)\n", init_path);
+
+ void *user_stack = (void*)(0x00007FFFFFFFFFFF);
+ mem_ensure_range((uintptr_t)user_stack & ~0xFFF, (uintptr_t)user_stack, true, true);
+
+ klogf("User entry point %#016X\n", entry_point);
+ umode_enter(entry_point, user_stack);
+}
diff --git a/usr/umode.d b/usr/umode.d
new file mode 100644
index 0000000..54c004b
--- /dev/null
+++ b/usr/umode.d
@@ -0,0 +1,3 @@
+usr/umode.o: usr/umode.c usr/umode.h usr/elf.h boot/cmdline.h \
+ lib/hashtable.h lib/linkedlist.h lib/jove.h ird/initrd.h ird/tar.h \
+ lib/linkedlist.h mem/memory.h mem/slab.h
diff --git a/usr/umode.h b/usr/umode.h
new file mode 100644
index 0000000..2755abe
--- /dev/null
+++ b/usr/umode.h
@@ -0,0 +1,8 @@
+#ifndef JOVE_UMODE_H
+#define JOVE_UMODE_H 1
+
+void umode_setup(void);
+
+void umode_enter(void (*entry)(void), void *stack);
+
+#endif