diff --git a/kernel/src/exec/elf.c b/kernel/src/exec/elf.c index 5cd8d9c..de0a3a4 100644 --- a/kernel/src/exec/elf.c +++ b/kernel/src/exec/elf.c @@ -47,6 +47,12 @@ program_t *elf_load(char *data, int user) { for (uint16_t i = 0; i < ehdr->e_phnum; i++) { log("elf - ELF segment type: %d\n", phdr[i].p_type); + + if (phdr[i].p_type == PT_INTERP) { + log("elf - A PT_INTERP program header was found. This was meant to be a dynamically-linked program, which Soaplin doesn't supports.\n"); + return NULL; + } + if (phdr[i].p_type != PT_LOAD) continue; @@ -58,7 +64,9 @@ program_t *elf_load(char *data, int user) { uint64_t flags = VMM_PRESENT; if (phdr[i].p_flags & PF_W) flags |= VMM_WRITABLE; - if (!(phdr[i].p_flags & PF_X)) + if (phdr[i].p_flags & PF_X) + flags &= ~VMM_NX; + else flags |= VMM_NX; if (user) diff --git a/kernel/src/main.c b/kernel/src/main.c index cedbcbe..3bfcb04 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -131,7 +131,7 @@ void __kmain(void) { sched_process *proc = - sched_create("Test", p->entry, p->pm, SCHED_USER_PROCESS); + sched_from_program(p); log("kernel - Soaplin initialized sucessfully.\n"); diff --git a/kernel/src/sched/sched.c b/kernel/src/sched/sched.c index d822096..9a998de 100644 --- a/kernel/src/sched/sched.c +++ b/kernel/src/sched/sched.c @@ -119,6 +119,10 @@ sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm, return proc; } +sched_process *sched_from_program(program_t *prog) { + // D̶̡͖̼̪̩̽̃̿͐͐̀̑͐̑ǫ̴͚̘̩̗̠̣̗͇̳̀̅̈͌͆͆ ̸̢̢̯͎̳̟̑͋́N̷̹͛̋͗ö̴͇̼̖̝̼́̀̾̿̾̓̔̌t̵̯̘͇̙̬̤̫͚͓̠͔̭̚ͅ ̵͔̲͈̭͛̆̈Ú̷̱̈́͑́̇̀̈́̔͝͠s̴̢͇̳̯̬͔̦̗̯̜̀̓̎̆̅̈́̈́̑̾͆͌̆͝ê̴̛͎̪̩̙͕̖͖͍͓͐̊̈͋̆̂̌̍̂͘͘̚ ̵̢̢͖̦̬͔̻͇̠̺̂͒͌͌̈́̇̏͑͋̓̔̅̓͂͝S̴̡͇͎̠̯͙̖̲̮͓͋͊̐̋̑́͂͆̿C̵̤̲͉̫̜͓͇̙͇̪̥̈̂́̈́͋̃̿̕H̶̡͓̠̝͉͋͋̎̃E̶͉̬̞̖̮͚̙͗̔̋͆Ḑ̴̛͎̙̥̱̱͎͊͊͋̈́̆̎̓͑̚̚_̷͚̯̻̖͈̳̺̖̈͗́̽͠Ḱ̴̮͓̲̠̫͈̆̿͂͂̀̂͆̀́̔͝ͅḘ̷̡͔̘̒̒̐͆̍̀R̵̭̰̐́̾̈́̈́̋͗̎̉͐͝N̴̰͆̂͛̂̈́̄̊͌̓͆̕͘͠͠Ě̴̥͙̼̳̩̠͓͕̫͔̘̠̻̀͌̓͑́̓̂̋̌͘͜L̴̙͓̣̭̙͙͈̺̩̄̈͆͆͒͗͛̈́̎̉̈́͘͘͜͠_̵̭̱͇͍̩̬͌̿͂͊̐͘̕ͅP̵̡̪̹̀͂̀̋̇̓͘͜Ŕ̸̭͍̮̼̙͓͕̳̫̇̏͌͌̋͜͝Ǫ̵̛͎̭̱͈̫̮̘͉͔̪̟̺̥̉̈̈́̊́̕̕͠ͅC̵̡̡͕̱̠̝̭͓̗̜͇̼̳̲͓̑̽̔̑͠Ę̷̛̦̑̈̒̃̊̈́̓̚̚͜͠͝Ş̴̥͇̬̱̠̟͙̳̖̿͗̀͌͊̽̐͒̃͜S̴͉͖͉͎͎̱̝͔̙̜̭̍͑͊̒͆̃͗̂͌̽͑̓ͅ ̶̼̥̜͙͈̦̲̰̞̈́̑͆̂͝H̸̩̭̹̘̩̊͗̔̉̓̈́ȩ̷̩͍͚̮̰̭̘͍͇͈̺͇̻̓̀̅̊́̓̈́͗̇̔̓͛͜͝ṙ̶̡̩̜̜̭̝̪͔͙̟̣͉̆͗̉͜͠͝ͅę̷̡̦̘̰͖̲͉̤̼͈̺̺̦̯̿͌́͐̃̃͂̾́̊́.̶̡̧͈͍͈̟̠͙̘̤̝̪̽̊̈͐̕͜ + return sched_create("unknown program", prog->entry, prog->pm, SCHED_USER_PROCESS); +} void sched_exit(int exit_code) { log("sched - Process %d exited with code %d!", curr_proc->pid, exit_code); curr_proc->type = SCHED_DIED; diff --git a/kernel/src/sched/sched.h b/kernel/src/sched/sched.h index 971b651..ee8089a 100644 --- a/kernel/src/sched/sched.h +++ b/kernel/src/sched/sched.h @@ -1,6 +1,7 @@ #pragma once #include "arch/x86_64/idt.h" +#include "exec/exec.h" #include "mm/vmm.h" #define SCHED_KERNEL_PROCESS 0 // A process that runs in kernel mode. @@ -38,5 +39,8 @@ extern sched_process *proc_list; void sched_init(); sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm, uint32_t flags); + +sched_process *sched_from_program(program_t *prog); + void sched_exit(int exit_code); void schedule(registers_t *regs); \ No newline at end of file diff --git a/kernel/src/sys/syscall.c b/kernel/src/sys/syscall.c index 1abefe6..61febba 100644 --- a/kernel/src/sys/syscall.c +++ b/kernel/src/sys/syscall.c @@ -14,7 +14,7 @@ extern void __x86_64_syscall_init(); static uint64_t __syscall_undefined() { return 0; } void syscall_handle(registers_t *regs) { - if (regs->rax > 1024) { + if (regs->rax >= 1024) { log("syscall - syscall_handle was called with rax better than what Soaplin " "supports (1024). did you forget to set rax?\n"); return; @@ -50,13 +50,15 @@ void syscall_register(int id, syscall handler) { log("syscall - System call %d has been set to %p\n", id, handler); } +extern void syscall_write(int fd, const char *buf, size_t count); extern void syscall_exit(int exit_code); void syscall_init() { for (int i = 0; i < 1024; i++) syscall_table[i] = (syscall)__syscall_undefined; - syscall_register(0, (syscall)syscall_exit); + syscall_register(1, (syscall)syscall_write); + syscall_register(60, (syscall)syscall_exit); __x86_64_syscall_init(); } \ No newline at end of file diff --git a/kernel/src/sys/syscalls/syscalls_fs.c b/kernel/src/sys/syscalls/syscalls_fs.c new file mode 100644 index 0000000..a89b106 --- /dev/null +++ b/kernel/src/sys/syscalls/syscalls_fs.c @@ -0,0 +1,11 @@ +#include +#include + +int syscall_write(int fd, const char *buf, size_t count) { + if (fd == 1) { + printf("%s", buf); // Prevent the buffer from being formatted. + return count; + } + + return 0; +} \ No newline at end of file diff --git a/testing/sk-hello.elf b/testing/sk-hello.elf index f22be1c..bf35426 100755 Binary files a/testing/sk-hello.elf and b/testing/sk-hello.elf differ diff --git a/testing/test.asm b/testing/test.asm index 96cf00e..762f01f 100644 --- a/testing/test.asm +++ b/testing/test.asm @@ -1,9 +1,18 @@ bits 64 + section .text global _start _start: - mov rax, 1025 + mov rax, 1 ; write syscall number + mov rdi, 1 ; stdout file descriptor + mov rsi, msg ; pointer to message + mov rdx, msg_len ; message length syscall + .loop: - jmp .loop \ No newline at end of file + jmp .loop + +section .data + msg db "Hello, World. Technically, this should work on both Soaplin & Linux.", 10 ; 10 is newline + msg_len equ $ - msg \ No newline at end of file diff --git a/testing/test.o b/testing/test.o index 3b2adb7..2e97fc6 100644 Binary files a/testing/test.o and b/testing/test.o differ