summaryrefslogtreecommitdiff
path: root/boot/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'boot/main.c')
-rw-r--r--boot/main.c76
1 files changed, 45 insertions, 31 deletions
diff --git a/boot/main.c b/boot/main.c
index d217235..12b411c 100644
--- a/boot/main.c
+++ b/boot/main.c
@@ -3,6 +3,8 @@
#include <asm/x86_64/msr.h>
#include <bits/x86_64/msr.h>
#include <bits/x86_64/descriptor.h>
+#include <libc/stdio.h>
+#include <posix/sys/mman.h>
/*
* Fake syscall mechanism -
@@ -43,15 +45,39 @@ static struct segment_descriptor const fake_syscall_gdt[] =
{ 0xffff, 0, 0, 0x92, 0xcf, 0}
};
-SYSV_ABI static void fake_syscall_handler(void)
+typedef uint64_t syscall_delegate_parameters[6];
+
+struct syscall_context_return_state
{
- while (true);
-}
+ uint64_t rflags; // 8
+ struct descriptor_table_register_long gdtr; // 24
+ uint64_t return_ds; // 32
+ uintptr_t return_rip; // 40
+ uint64_t return_cs; // 48
+};
+
+struct syscall_context
+{
+ uint64_t pad; // 8
+ uint64_t syscall_index; // 16
+ syscall_delegate_parameters parameters; // 64
+ struct syscall_context_return_state state;
+};
+
+typedef int64_t (syscall_delegate)(syscall_delegate_parameters params);
+
+//constexpr int NR_SYSCALLS = 10;
+//static syscall_delegate *syscall_handler_delegates[NR_SYSCALLS];
-static void *return_rsp;
+SYSV_ABI int64_t fake_syscall_handler(uint64_t syscall_index, struct syscall_context *context)
+{
+ (void)syscall_index;
+ (void)context;
+ return -1;
+}
SYSV_ABI void fake_syscall_entry(void);
-SYSV_ABI void fake_syscall_return(void *target_rsp, void **return_rsp, SYSV_ABI void (*callback)());
+SYSV_ABI void fake_syscall_start(void *stack);
static void install_syscall_handler(void)
{
@@ -66,37 +92,24 @@ static void install_syscall_handler(void)
msr_write(MSR_INDEX_EFER, efer);
}
-struct context_stack_frame
-{
- struct descriptor_table_register_long lret_gdtr;
- uint64_t lret_ds;
- uint64_t lret_rip;
- uint64_t lret_cs;
-};
-
-static void enter_boot_image(struct kjarna_boot_image *image)
+static void *create_fake_syscall_stack(void *entry_addr)
{
- size_t boot_stack_size = 0x10000;
- char *boot_image_stack = calloc(1, boot_stack_size);
- void *boot_image_stack_head = boot_image_stack + boot_stack_size;
+ constexpr size_t fake_syscall_stack_size = 0x20000; // 128KiB stack
+ char *stack_pointer_base = mmap(nullptr, fake_syscall_stack_size, 0, 0, -1, 0);
+ void *stack_pointer_head = stack_pointer_base + fake_syscall_stack_size;
- struct context_stack_frame *stack_frame = stack_alloc(&boot_image_stack_head, sizeof(*stack_frame));
+ struct syscall_context *context = stack_alloc(&stack_pointer_head, sizeof(*context));
- stack_frame->lret_cs = 8;
- stack_frame->lret_ds = 16;
- stack_frame->lret_rip = (uintptr_t)image->entry;
+ context->state.rflags = 0;
+ context->state.gdtr.base = (uintptr_t)&fake_syscall_gdt;
+ context->state.gdtr.limit = sizeof(fake_syscall_gdt) - 1;
+ context->state.return_ds = 16;
+ context->state.return_cs = 8;
+ context->state.return_rip = (uintptr_t)entry_addr;
- stack_frame->lret_gdtr.limit = sizeof(fake_syscall_gdt) - 1;
- stack_frame->lret_gdtr.base = (uintptr_t)fake_syscall_gdt;
-
-
- fake_syscall_return(boot_image_stack_head, &return_rsp, fake_syscall_handler);
-
- while (true);
+ return stack_pointer_head;
}
-#include <libc/stdio.h>
-
int main(int argc, char **argv)
{
(void)argc;
@@ -104,6 +117,7 @@ int main(int argc, char **argv)
struct kjarna_boot_image boot_image = get_boot_image();
install_syscall_handler();
- enter_boot_image(&boot_image);
+ void *fake_syscall_stack = create_fake_syscall_stack((void *)boot_image.entry);
+ fake_syscall_start(fake_syscall_stack);
}