summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAda Christine <adachristine18@gmail.com>2025-02-01 18:33:53 +0000
committerAda Christine <adachristine18@gmail.com>2025-02-01 18:33:53 +0000
commit9792d78c44ebddd128785a00358cbf38ac714d5d (patch)
tree0de4bc192145cf469f308e5f1ef0ab025cb703d2
parent2fb3f208bd2e739a8968afb23d22e13b6660ca22 (diff)
this is starting to work
-rw-r--r--api/bits/x86_64/descriptor.h2
-rw-r--r--boot/fake_syscall_entry.S89
-rw-r--r--boot/main.c76
-rw-r--r--lldbscript2
4 files changed, 114 insertions, 55 deletions
diff --git a/api/bits/x86_64/descriptor.h b/api/bits/x86_64/descriptor.h
index 649ac74..c0c00f6 100644
--- a/api/bits/x86_64/descriptor.h
+++ b/api/bits/x86_64/descriptor.h
@@ -4,7 +4,7 @@ struct descriptor_table_register_long
{
uint16_t limit;
uint64_t base;
-} __attribute__((packed, aligned(16)));
+} __attribute__((packed, aligned(8)));
struct segment_descriptor
{
diff --git a/boot/fake_syscall_entry.S b/boot/fake_syscall_entry.S
index bc175c1..8a3f8c8 100644
--- a/boot/fake_syscall_entry.S
+++ b/boot/fake_syscall_entry.S
@@ -1,34 +1,79 @@
.section .text
.global fake_syscall_entry
-.global fake_syscall_return
+.global fake_syscall_start
.extern fake_syscall_handler
-fake_syscall_entry:
- hlt;
-
-fake_syscall_return:
+fake_syscall_start:
cli
-fake_syscall_swap:
- mov %cs, %rax
- pushq %rax
- pushq %rdx
- mov %ds, %rax
- pushq %rax
- sub $16, %rsp
- sgdt (%rsp)
- mov %rsp, (%rsi)
mov %rdi, %rsp
- lgdt (%rsp)
- add $16, %rsp
- movw (%rsp), %ds
- movw (%rsp), %es
- movw (%rsp), %fs
- movw (%rsp), %gs
- movw (%rsp), %ss
+ jmp .L_fake_syscall_return
+
+/*
+ SYSCALL STACK FRAME - FROM LOWER TO HIGHER ADDRESS
+
+ 0 pad
+ 8 syscall_index
+ 16 parameters[0]
+ 24 parameters[1]
+ 32 parameters[2]
+ 40 parameters[3]
+ 48 parameters[4]
+ 56 parameters[5]
+ 64 state.rflags
+ 72 state.gdtr.base:2 state.gdtr.limit:6
+ 80 state.gdtr.limit:2 [unused]:6
+ 88 state.return_ds
+ 96 state.return_rip
+ 104 state.return_cs
+*/
+
+fake_syscall_entry:
+ sub $112, %rsp
+ mov %rax, 8(%rsp)
+ mov %rdi, 16(%rsp)
+ mov %rsi, 24(%rsp)
+ mov %rdx, 32(%rsp)
+ mov %r10, 40(%rsp)
+ mov %r8, 48(%rsp)
+ mov %r9, 56(%rsp)
+
+ pushfq
+ pop %rdi
+ mov %rdi, 64(%rsp)
+
+ sgdt 72(%rsp)
+ movw %ds, 88(%rsp)
+ mov %rcx, 96(%rsp)
+ movw %cs, 104(%rsp)
+
+ mov %rsp, %rdi
+ call fake_syscall_handler
+
+ push %rbp
+ mov %rsp, %rbp
+ add $64, %rsp
+ popfq
+ mov %rbp, %rsp
+ pop %rbp
+
+.L_fake_syscall_return:
+ lgdt 72(%rsp)
+ mov 88(%rsp), %rdi
+ mov %di, %ds
+ mov %di, %es
+ mov %di, %fs
+ mov %di, %gs
+ mov %di, %ss
- add $8, %rsp
+ mov 16(%rsp), %rdi
+ mov 24(%rsp), %rsi
+ mov 32(%rsp), %rdx
+ mov 40(%rsp), %r10
+ mov 48(%rsp), %r8
+ mov 56(%rsp), %r9
+ add $96, %rsp
lretq
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);
}
diff --git a/lldbscript b/lldbscript
index 3f94ba2..6d134f5 100644
--- a/lldbscript
+++ b/lldbscript
@@ -3,5 +3,5 @@ target modules add service/kjarna.os
gdb-remote localhost:1234
target modules load --file kjarna.efi .text 0x6184000 .data 0x6189000
target modules load --file kjarna.os --slide 0x6178000
-b enter_boot_image
+b main