diff options
-rw-r--r-- | src/init/main.c | 12 | ||||
-rw-r--r-- | src/kernel/arch/generic.h | 4 | ||||
-rw-r--r-- | src/kernel/arch/i386/pagedir.c | 27 | ||||
-rw-r--r-- | src/kernel/syscalls.c | 32 | ||||
-rw-r--r-- | src/kernel/syscalls.h | 6 |
5 files changed, 70 insertions, 11 deletions
diff --git a/src/init/main.c b/src/init/main.c index 6c4ccc3..fda68b7 100644 --- a/src/init/main.c +++ b/src/init/main.c @@ -1,15 +1,23 @@ +#include <kernel/syscalls.h> +#include <stddef.h> #include <stdint.h> int _syscall(int, int, int, int); +int debuglog(const char *msg, size_t len) { + return _syscall(SC_DEBUGLOG, (void*)msg, len, 0); +} + + int main() { - uint8_t color = _syscall(1, 2, 3, 4); + debuglog("hello from init! ", + sizeof("hello from init! ") - 1); // change the colors of VGA text // doesn't require a lot of code, but still shows that it's working uint8_t *vga = (void*) 0xB8000; for (int i = 0; i < 80 * 25; i++) - vga[(i << 1) + 1] = color; + vga[(i << 1) + 1] = 0x4e; // try to mess with kernel memory uint8_t *kernel = (void*) 0x100000; diff --git a/src/kernel/arch/generic.h b/src/kernel/arch/generic.h index 0b005a2..6200320 100644 --- a/src/kernel/arch/generic.h +++ b/src/kernel/arch/generic.h @@ -24,3 +24,7 @@ struct pagedir *pagedir_new(); void pagedir_map(struct pagedir *dir, void *virt, void *phys, bool user, bool writeable); void pagedir_switch(struct pagedir *); + +// return 0 on failure +void *pagedir_virt2phys(struct pagedir *dir, const void *virt, + bool user, bool writeable); diff --git a/src/kernel/arch/i386/pagedir.c b/src/kernel/arch/i386/pagedir.c index 8ab406d..02361e6 100644 --- a/src/kernel/arch/i386/pagedir.c +++ b/src/kernel/arch/i386/pagedir.c @@ -91,3 +91,30 @@ void pagedir_map(struct pagedir *dir, void *virt, void *phys, void pagedir_switch(struct pagedir *dir) { asm volatile("mov %0, %%cr3;" : : "r" (dir) : "memory"); } + +void *pagedir_virt2phys(struct pagedir *dir, const void *virt, + bool user, bool writeable) +{ + uintptr_t virt_casted = (uintptr_t) virt; + uintptr_t phys; + uint32_t pd_idx = virt_casted >> 22; + uint32_t pt_idx = virt_casted >> 12 & 0x03FF; + struct pagetable_entry *pagetable, page; + + /* DOESN'T CHECK PERMISSIONS ON PAGE DIRS, TODO + * while i don't currently see a reason to set permissions + * directly on page dirs, i might see one in the future. + * leaving this as-is would be a security bug */ + if (!dir->e[pd_idx].present) return 0; + + pagetable = (void*)(dir->e[pd_idx].address << 11); + page = pagetable[pt_idx]; + + if (!page.present) return 0; + if (user && !page.user) return 0; + if (writeable && !page.writeable) return 0; + + phys = page.address << 11; + phys |= (uintptr_t)virt & 0xFFF; + return (void*)phys; +} diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index a42dc44..2af8cf9 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -1,15 +1,29 @@ #include <kernel/arch/generic.h> #include <kernel/panic.h> +#include <kernel/proc.h> +#include <kernel/syscalls.h> +#include <stdint.h> -int syscall_handler(int a, int b, int c, int d) { - // verify that the parameters get passed correctly - if (a != 1) panic(); - if (b != 2) panic(); - if (c != 3) panic(); - if (d != 4) panic(); +int sc_debuglog(const char *msg, size_t len) { + struct pagedir *pages = process_current->pages; + void *phys = pagedir_virt2phys(pages, msg, true, false); - log_const("in a syscall!"); + // page overrun check + if (((uintptr_t)msg & PAGE_MASK) + len > PAGE_SIZE) + len = PAGE_SIZE - ((uintptr_t)msg & PAGE_MASK); + if (((uintptr_t)msg & PAGE_MASK) + len > PAGE_SIZE) + panic(); // just in case I made an off by 1 error - // used to check if the return value gets passed correctly - return 0x4e; + log_write(phys, len); + return len; +} + +int syscall_handler(int num, int a, int b, int c) { + switch (num) { + case SC_DEBUGLOG: + return sc_debuglog((void*)a, b); + default: + log_const("unknown syscall "); + panic(); + } } diff --git a/src/kernel/syscalls.h b/src/kernel/syscalls.h new file mode 100644 index 0000000..39db6a9 --- /dev/null +++ b/src/kernel/syscalls.h @@ -0,0 +1,6 @@ +#pragma once + +// not caring about stable syscall numbers just yet +enum { + SC_DEBUGLOG +}; |