diff options
| author | Ada Christine <adachristine18@gmail.com> | 2025-02-01 23:25:40 +0000 |
|---|---|---|
| committer | Ada Christine <adachristine18@gmail.com> | 2025-02-01 23:25:40 +0000 |
| commit | 3d806c9e2fcb6226915982b6514919a3b9dac4dc (patch) | |
| tree | cae747e3a5c6e31f89069e0ba1a7ae90cc4b85d9 /boot | |
| parent | f76631c47b92b0778b1073bcab55dc1240422f20 (diff) | |
write syscall functions
Diffstat (limited to 'boot')
| -rw-r--r-- | boot/fake_syscall_entry.S | 15 | ||||
| -rw-r--r-- | boot/main.c | 108 |
2 files changed, 101 insertions, 22 deletions
diff --git a/boot/fake_syscall_entry.S b/boot/fake_syscall_entry.S index 9daa0d5..f75c2d7 100644 --- a/boot/fake_syscall_entry.S +++ b/boot/fake_syscall_entry.S @@ -5,17 +5,7 @@ .extern fake_syscall_handler -fake_syscall_start: - cli - mov %rdi, %rsp - jmp .L_fake_syscall_return - /* - Fake syscall mechanism - - The Kjarna kernel runtime loader/linker is started by the Kjarna boot kernel and supported - by a subset of system calls in order to load files and place them in virtual memory. - SYSCALL STACK FRAME - FROM LOWER TO HIGHER ADDRESS 0 pad @@ -34,6 +24,11 @@ fake_syscall_start: 104 state.return_cs */ +fake_syscall_start: + cli + mov %rdi, %rsp + jmp .L_fake_syscall_return + fake_syscall_entry: sub $112, %rsp mov %rax, 8(%rsp) diff --git a/boot/main.c b/boot/main.c index 611c833..ed18578 100644 --- a/boot/main.c +++ b/boot/main.c @@ -5,6 +5,7 @@ #include <bits/x86_64/descriptor.h> #include <libc/stdio.h> #include <posix/sys/mman.h> +#include <posix/unistd.h> /* * Fake syscall mechanism - @@ -47,32 +48,114 @@ static struct segment_descriptor const fake_syscall_gdt[] = typedef uint64_t syscall_delegate_parameters[6]; +static struct +{ + uint16_t cs; + uint16_t ds; + uint64_t rflags; + struct descriptor_table_register_long gdtr; +} +uefi_context; + +static void save_uefi_context() +{ + __asm__ volatile ( + "movw %%cs, %0\n" + "movw %%ds, %1\n" + "pushfq\n" + "popq %3\n" + "sgdt %2\n" + : + "=m"(uefi_context.cs), + "=m"(uefi_context.ds), + "=m"(uefi_context.gdtr), + "=g"(uefi_context.rflags) + : + ); +} + +static void restore_uefi_context() +{ + __asm__ volatile ( + "lgdt %0\n" + "mov %w1, %%ds\n" + "mov %w1, %%es\n" + "mov %w1, %%fs\n" + "mov %w1, %%gs\n" + "mov %w1, %%gs\n" + "mov %w1, %%ss\n" + "push %q2\n" + "lea .Lflush(%%rip), %%rax\n" + "push %%rax\n" + "lretq\n" + ".Lflush:\n" + "push %q3\n" + "popfq\n" + : + : + "m"(uefi_context.gdtr), + "m"(uefi_context.ds), + "m"(uefi_context.cs), + "g"(uefi_context.rflags) + : + "rax" + ); + +} + struct syscall_context_return_state { - 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 + uint64_t rflags; + struct descriptor_table_register_long gdtr; + uint64_t return_ds; + uintptr_t return_rip; + uint64_t return_cs; }; struct syscall_context { - uint64_t pad; // 8 - uint64_t syscall_index; // 16 - syscall_delegate_parameters parameters; // 64 + uint64_t pad; + uint64_t syscall_index; + syscall_delegate_parameters parameters; 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]; +int64_t syscall_delegate_write(syscall_delegate_parameters params) +{ + return write((int)params[0], (void *)params[1], (size_t)params[2]); +} + +constexpr int NR_SYSCALLS = 10; +static syscall_delegate *syscall_handler_delegates[NR_SYSCALLS] = +{ + nullptr, + syscall_delegate_write +}; SYSV_ABI int64_t fake_syscall_handler(struct syscall_context *context) { - (void)context; - return -1; + if (context->syscall_index > NR_SYSCALLS) + { + // TODO: ENOSYS + return -1; + } + + syscall_delegate *delegate = syscall_handler_delegates[context->syscall_index]; + + if (delegate == nullptr) + { + // TODO: ENOSYS + return -1; + } + + restore_uefi_context(); + int64_t result = delegate(context->parameters); + save_uefi_context(); + + return result; } SYSV_ABI void fake_syscall_entry(void); @@ -117,6 +200,7 @@ int main(int argc, char **argv) struct kjarna_boot_image boot_image = get_boot_image(); install_syscall_handler(); void *fake_syscall_stack = create_fake_syscall_stack((void *)boot_image.entry); + save_uefi_context(); fake_syscall_start(fake_syscall_stack); } |
