diff options
56 files changed, 466 insertions, 954 deletions
@@ -1,7 +1,6 @@ include $(CONFIG) include config.mk -CDIRS := boot lib hal proc sys api panic CDIRS += boot/$(TARGET_BOOTLOADER) CFILES := $(wildcard *.c) @@ -10,18 +10,16 @@ enum { INIT_ROOTDIR_PROCESSORS_I, INIT_ROOTDIR_FREEMEMORY_I, INIT_ROOTDIR_HWMEMORY_I, + INIT_ROOTDIR_MODULES_I, INIT_ROOTDIR_INTERRUPTS_I, INIT_ROOTDIR_INITRD_I, INIT_ROOTDIR_MESSAGE_I, - INIT_ROOTDIR_FRAMEBUFFER_I, - INIT_ROOTDIR_VIRTTERM_I, _INIT_ROOTDIR_LAST_I }; #ifdef __x86_64__ enum { INIT_ROOTDIR_IOPB_I = _INIT_ROOTDIR_LAST_I, - INIT_ROOTDIR_SERIAL_COM_I, _INIT_ROOTDIR_LAST_ARCH_I }; #endif @@ -30,6 +28,7 @@ struct init_payload { void *rsdp; uintptr_t brk; + uintptr_t fb_base; }; #endif @@ -15,9 +15,6 @@ enum JOVE_OBJ_SHMEMORY, JOVE_OBJ_INT_HANDLE, JOVE_OBJ_PCB, - JOVE_OBJ_INITRD_FILE, - JOVE_OBJ_FRAMEBUFFER, - JOVE_OBJ_VIRTTERM, JOVE_OBJ_MESSAGE, JOVE_OBJ_LINK, }; @@ -35,6 +32,8 @@ enum #define OBJDIR_SIZE 0x1000 #define OBJDIR_ENTRIES (OBJDIR_SIZE / sizeof(uintmax_t)) +#define SHMEMORY_MAX_PAGES 0xFFF + #define MESSAGE_ALIGN 0x1000 #define MESSAGE_SIZE 0x1000 diff --git a/api/syscall.h b/api/syscall.h index 40fedd4..62b9917 100644 --- a/api/syscall.h +++ b/api/syscall.h @@ -32,7 +32,7 @@ struct syscall_generic_write struct syscall_generic_objpath { - uint16_t pathlen; + objpath_part_t pathlen; objpath_part_t path[]; }; @@ -63,7 +63,7 @@ enum struct syscall_untyped_split { size_t bytes; - uint16_t dest_pathlen; + objpath_part_t dest_pathlen; objpath_part_t dest_path[]; }; @@ -130,25 +130,25 @@ struct syscall_pagedir_flags struct syscall_pagedir_map { - struct syscall_pagedir_flags page_flags; - uint16_t untyped_pathlen; uintptr_t virtual_address; + struct syscall_pagedir_flags page_flags; + objpath_part_t untyped_pathlen; objpath_part_t untyped_path[]; }; struct syscall_pagedir_map_shmem { - struct syscall_pagedir_flags page_flags; - uint8_t page_offset; - uint16_t shmem_pathlen; uintptr_t virtual_address; + unsigned short page_offset; + struct syscall_pagedir_flags page_flags; + objpath_part_t shmem_pathlen; objpath_part_t shmem_path[]; }; struct syscall_pagedir_unmap { uintptr_t virtual_address; - uint16_t none_pathlen; + objpath_part_t none_pathlen; objpath_part_t none_path[]; }; @@ -232,7 +232,7 @@ struct syscall_pcb_send { pid_t send_target; uintmax_t send_timeout; - uint16_t send_path_length; + objpath_part_t send_path_length; objpath_part_t send_path[]; }; @@ -240,7 +240,7 @@ struct syscall_pcb_recv { pid_t recv_target; uintmax_t recv_timeout; - uint16_t recv_path_length; + objpath_part_t recv_path_length; objpath_part_t recv_path[]; }; @@ -256,7 +256,7 @@ struct syscall_pcb_swap struct syscall_pcb_stack { - char type; + unsigned char type; objpath_part_t stack_path_length; objpath_part_t stack_path[]; }; diff --git a/arch/x86_64/boot/limine/framebuffer.c b/arch/x86_64/boot/limine/framebuffer.c deleted file mode 100644 index 637a7fc..0000000 --- a/arch/x86_64/boot/limine/framebuffer.c +++ /dev/null @@ -1,51 +0,0 @@ -#include "arch/x86_64/hal/paging.h" -#include "jove.h" -#include "config.h" -#include "hal/framebuffer.h" -#include "lib/string.h" -#include "lib/printf.h" - -/*We don't know the size of the framebuffer until runtime, but at the same - * time we don't want to dynamically allocate from physical memory. In this - * case we allocate memory for the maximum supported framebuffer at compile - * time and only use what we need at runtime.*/ -#define FRAMEBUFFER_MAX_BYTES (FRAMEBUFFER_MAX_WIDTH * FRAMEBUFFER_MAX_WIDTH * 4) -#define FRAMEBUFFER_MAX_PAGES ((FRAMEBUFFER_MAX_BYTES + 4095) / 0x1000) -#define FRAMEBUFFER_MAX_HUGEPAGES ((FRAMEBUFFER_MAX_PAGES + 511) / 512) -#define FRAMEBUFFER_MAX_GIANTPAGES ((FRAMEBUFFER_MAX_HUGEPAGES + 511) / 512) - -PAGEALIGN static page_t fb_pages[FRAMEBUFFER_MAX_GIANTPAGES + FRAMEBUFFER_MAX_HUGEPAGES][512]; - -extern page_t _kernel_pml4[512]; - -void* -fb_remap(uintptr_t fb_address, - size_t fb_bytes) -{ - fb_address &= ~IDENT_VIRT_BASE; - size_t fb_numpages = (fb_bytes + 4095) >> 12; - - if(fb_numpages > FRAMEBUFFER_MAX_PAGES) { - kprintf("Framebuffer is too big! Please recompile the kernel with a bigger framebuffer allowance!"); - return NULL; - } - - uintptr_t vptr = IDENT_VIRT_BASE | (511ULL << PMLI_SHL(3)); - size_t last_table = 0; - for(size_t page = 0; page < fb_numpages; page++) { - uintptr_t frame = fb_address + (page << 12); - uintptr_t frame_virt = vptr + (page << 12); - - int tblres = 0; - do { - uintptr_t tbl_frame = KPTR_TOPHYS(&fb_pages[last_table++]); - tblres = pagedir_map_table(_kernel_pml4, tbl_frame, frame_virt); - if(tblres == EHASMAP) last_table--; - } while(tblres == 0); - - pagedir_map_frame(_kernel_pml4, frame, frame_virt, - PAGE_GLOBAL | PAGE_WRITEABLE | PAGE_XD); - } - - return (void*)vptr; -} diff --git a/arch/x86_64/debug/debug.c b/arch/x86_64/debug/debug.c new file mode 100644 index 0000000..5b2c918 --- /dev/null +++ b/arch/x86_64/debug/debug.c @@ -0,0 +1,10 @@ +#include "debug/debug.h" +#include "arch/x86_64/hal/serial_com.h" + +void _debug_init_arch(void) +{ + #ifdef DEBUG_SERIAL + _debug_has_output = true; + serial_com_init(); + #endif +} diff --git a/arch/x86_64/debug/printf.c b/arch/x86_64/debug/printf.c new file mode 100644 index 0000000..13737b9 --- /dev/null +++ b/arch/x86_64/debug/printf.c @@ -0,0 +1,20 @@ +#include "lib/printf.h" +#include "../hal/serial_com.h" +#include "api/error.h" +#include "debug/debug.h" + +int +kvprintf(const char *fmt, va_list ap) +{ + if(!_debug_has_output) return -EBADCALL; + + char buffer[256] = { 0 }; + int r = vsnprintf(buffer, 256, fmt, ap); + int wlen = (r > 256 ? 256 : r); + +#ifdef DEBUG_SERIAL + serial_com_write(SERIAL_COM1, buffer, wlen); +#endif + + return r; +} diff --git a/arch/x86_64/hal/gdt.c b/arch/x86_64/hal/gdt.c index fc7aa8b..8bfe942 100644 --- a/arch/x86_64/hal/gdt.c +++ b/arch/x86_64/hal/gdt.c @@ -63,7 +63,7 @@ gdt_setup(processor_t *processor) load_gdt(&gdtr); uintptr_t tss_base = (uintptr_t)&processor->tss; - size_t tss_limit = sizeof(struct tss); + size_t tss_limit = sizeof(struct tss) + 0x2000; struct gdt_entry *tss_lo = &processor->gdt[GDT_TSS_LO]; struct gdt_entry *tss_hi = &processor->gdt[GDT_TSS_HI]; diff --git a/arch/x86_64/hal/idt.c b/arch/x86_64/hal/idt.c index ff7a8a0..7b8bd52 100644 --- a/arch/x86_64/hal/idt.c +++ b/arch/x86_64/hal/idt.c @@ -20,8 +20,7 @@ struct int_user_handle __int_user_handles[IDT_ENTRIES]; static struct int_stackframe* s_int_handle_stub(struct int_stackframe* frame) { - kprintf("Unhandled interrupt %i at %p\n", frame->int_num, frame->int_rip); - hcf(); + kpanic_istate(frame, "Unhandled interrupt %i at %p\n", frame->int_num, frame->int_rip); } struct int_stackframe* diff --git a/arch/x86_64/hal/serial_com.c b/arch/x86_64/hal/serial_com.c index 372a433..c571057 100644 --- a/arch/x86_64/hal/serial_com.c +++ b/arch/x86_64/hal/serial_com.c @@ -1,10 +1,8 @@ +#ifdef DEBUG_SERIAL + #include "serial_com.h" #include "port.h" #include "jove.h" -#include "hal/obj.h" -#include "proc/init.h" -#include "lib/printf.h" -#include "sys/objdir.h" static int serial_com_recv(uint16_t port) @@ -67,27 +65,15 @@ serial_com_init(void) if(serial_com_init_port(SERIAL_COM1, 3)) { return; } - - { - jove_owned_obj_t *com_obj = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_SERIAL_COM_I); - obj_settype(com_obj, JOVE_OBJ_SERIAL_COM); - obj_setvalue(com_obj, SERIAL_COM1); - obj_release(com_obj); - } - - kprintf("Initialized COM1 on port %X for obj %X\n", SERIAL_COM1, INIT_ROOTDIR_SERIAL_COM_I); } int -serial_com_write( - jove_owned_obj_t *obj, - const char *s, size_t len) +serial_com_write(uint16_t port, const char *s, size_t len) { - if(obj_gettype(obj) != JOVE_OBJ_SERIAL_COM) { - reterr(EBADOBJ); - } for(size_t i = 0; i < len; i++) { - serial_com_putc((uint16_t)obj_getvalue(obj), s[i]); + serial_com_putc(port, s[i]); } return len; } + +#endif diff --git a/arch/x86_64/hal/serial_com.h b/arch/x86_64/hal/serial_com.h index 2dbb0cd..cf0badc 100644 --- a/arch/x86_64/hal/serial_com.h +++ b/arch/x86_64/hal/serial_com.h @@ -2,7 +2,7 @@ #define _JOVE_SERIAL_COM_H 1 #include <stdint.h> -#include "obj.h" +#include <stddef.h> #define SERIAL_COM1 0x3F8 @@ -19,8 +19,12 @@ #define SERIAL_COM_DLAB_BAUD_LO(com) (com) #define SERIAL_COM_DLAB_BAUD_HI(com) (com + 1) +#ifdef DEBUG_SERIAL + void serial_com_init(void); -int serial_com_write(jove_owned_obj_t *obj, const char *s, size_t len); +int serial_com_write(uint16_t port, const char *s, size_t len); + +#endif #endif diff --git a/arch/x86_64/hal/smp.c b/arch/x86_64/hal/smp.c index 7d94340..931a89f 100644 --- a/arch/x86_64/hal/smp.c +++ b/arch/x86_64/hal/smp.c @@ -45,15 +45,14 @@ smp_init_bsp(void) processor_t *bsp = &s_processors[0]; { - jove_owned_obj_t *processor_objdir_obj = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_PROCESSORS_I); - obj_settype(processor_objdir_obj, JOVE_OBJ_OBJDIR); - obj_setvalue(processor_objdir_obj, (uintptr_t)&s_processor_objdir); + jove_owned_obj_t *processor_objdir = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_PROCESSORS_I); + obj_settype(processor_objdir, JOVE_OBJ_OBJDIR); + obj_setvalue(processor_objdir, (uintptr_t)&s_processor_objdir); + jove_obj_t *processor_objdir_obj = obj_release(processor_objdir); jove_owned_obj_t *bsp_obj = objdir_getlocal(processor_objdir_obj, 0); init_processor(bsp, bsp_obj); - obj_release(bsp_obj); - obj_release(processor_objdir_obj); } idt_init(); diff --git a/arch/x86_64/lib/printf.c b/arch/x86_64/lib/printf.c deleted file mode 100644 index db47f6b..0000000 --- a/arch/x86_64/lib/printf.c +++ /dev/null @@ -1,25 +0,0 @@ -#include "../hal/serial_com.h" -#include "lib/printf.h" -#include "lib/virtterm.h" -#include "proc/init.h" -#include "sys/objdir.h" - -int -kvprintf(const char *fmt, va_list ap) -{ - char buffer[256] = { 0 }; - int r = vsnprintf(buffer, 256, fmt, ap); - int wlen = (r > 256 ? 256 : r); - - { - jove_owned_obj_t *serial_obj = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_SERIAL_COM_I); - serial_com_write(serial_obj, buffer, wlen); - obj_release(serial_obj); - - jove_owned_obj_t *vt_obj = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_VIRTTERM_I); - vt_write(vt_obj, buffer, wlen); - obj_release(vt_obj); - } - - return r; -} diff --git a/arch/x86_64/main.c b/arch/x86_64/main.c index 4a40707..4317c46 100644 --- a/arch/x86_64/main.c +++ b/arch/x86_64/main.c @@ -3,17 +3,15 @@ #include "proc/init.h" #include "lib/string.h" #include "lib/printf.h" -#include "lib/virtterm.h" #include "panic/panic.h" #include "../../hal/obj.h" #include "hal/msr.h" #include "hal/serial_com.h" #include "hal/smp.h" #include "hal/memory.h" -#include "hal/framebuffer.h" #include "proc/process.h" -#include "boot/initrd.h" -#include "boot/cmdline.h" +#include "boot/boot.h" +#include "debug/debug.h" int errno = 0; @@ -27,22 +25,20 @@ static void kernel_process_entry(void); void kernel_entry(void) { + debug_init(); + memset(&_rootdir, 0, 0x1000); obj_take(_rootdir_obj); obj_settype(_rootdir_obj, JOVE_OBJ_OBJDIR); obj_setvalue(_rootdir_obj, (uintptr_t)&_rootdir); + obj_release(_rootdir_obj); msr_enable_sse(); - obj_settype(_rootdir_obj, JOVE_OBJ_OBJDIR); - serial_com_init(); - smp_init_bsp(); - mem_setup_regions(); - initrd_setup(); - fb_init(); - vt_init(); + mem_setup_modules(); + mem_setup_regions(); cmdline_print(); diff --git a/arch/x86_64/proc/init.c b/arch/x86_64/proc/init.c index 8003a6d..6c5c36e 100644 --- a/arch/x86_64/proc/init.c +++ b/arch/x86_64/proc/init.c @@ -11,8 +11,7 @@ #include "lib/printf.h" #include "arch/x86_64/lib/elf.h" #include "arch/x86_64/hal/paging.h" -#include "boot/cmdline.h" -#include "boot/initrd.h" +#include "boot/boot.h" static int elf_is_valid(struct elf_header *ehdr) @@ -52,15 +51,13 @@ init_setup(void) kpanic("Kernel commandline is missing 'init' arg.\n"); } - jove_owned_obj_t *initrd_obj = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_INITRD_I); - jove_owned_obj_t *init_obj = initrd_seek(initrd_obj, init_path); - if(init_obj == NULL) { - kpanic("init: Cannot find file '%s' in initrd.\n", init_path); + jove_owned_obj_t *init_obj = boot_getmodule(init_path); + if(init_obj == 0) { + kpanic("Unable to get module %s : %s\n", init_path, errstr(errno)); } - obj_release(initrd_obj); - void *init_data = initrd_file_data(init_obj); - obj_release(init_obj); + void *init_data = shmem_deref(init_obj); + kprintf("Found init at %p\n", init_data); struct elf_header *init_ehdr = init_data; if(init_ehdr == NULL) { diff --git a/arch/x86_64/proc/scheduler.c b/arch/x86_64/proc/scheduler.c index 49a0c4d..6c748c7 100644 --- a/arch/x86_64/proc/scheduler.c +++ b/arch/x86_64/proc/scheduler.c @@ -1,5 +1,7 @@ #include "proc/scheduler.h" #include "arch/x86_64/hal/gdt.h" +#include "arch/x86_64/hal/obj.h" +#include "lib/printf.h" #include "lib/string.h" #include "process.h" #include "../hal/smp.h" @@ -12,10 +14,15 @@ _scheduler_switch_pcb_arch(pcb_t *target) proc->syscall_page = target->interrupt_page; proc->interrupt_page = target->interrupt_page; + proc->tss.rsp[0] = __interrupt_stack + 0xFF8; + if(target->iopb) { proc->tss.iopb = sizeof(struct tss); jove_owned_obj_t *iopb_obj = obj_take(target->iopb); - memcpy(proc->iopb, obj_deref(iopb_obj), sizeof(proc->iopb)); + if(obj_gettype(iopb_obj) != JOVE_OBJ_IOPB) { + memcpy(proc->iopb, obj_deref(iopb_obj), sizeof(proc->iopb)); + } + obj_release(iopb_obj); }else{ proc->tss.iopb = 0xff; } diff --git a/arch/x86_64/sys/syscall.c b/arch/x86_64/sys/syscall.c index 1e06e61..2a5ce08 100644 --- a/arch/x86_64/sys/syscall.c +++ b/arch/x86_64/sys/syscall.c @@ -6,7 +6,7 @@ #include "syscall.h" syscall_handle_t s_arch_handles[128] = { - [JOVE_OBJ_SERIAL_COM-0x80] = _syscall_handle_serial + NULL }; int @@ -50,5 +50,7 @@ void _syscall_entry(void) sysretq" :: [pcb] "i"(offsetof(processor_t, pcb)), - [ksp] "i"(offsetof(struct pcb_header, ksp))); + [ksp] "i"(offsetof(struct pcb_header, ksp)) + : "memory"); } + diff --git a/arch/x86_64/sys/syscall_serial.c b/arch/x86_64/sys/syscall_serial.c deleted file mode 100644 index 786a78b..0000000 --- a/arch/x86_64/sys/syscall_serial.c +++ /dev/null @@ -1,33 +0,0 @@ -#include "jove.h" -#include "lib/printf.h" -#include "sys/syscall.h" -#include "syscall.h" -#include "arch/x86_64/hal/serial_com.h" - -static int -s_syscall_serial_write( - jove_owned_obj_t *serial_com, - size_t payload_bytes, - void *payload_data) -{ - size_t bytes_needed = sizeof(struct syscall_generic_write); - CHECK_TOOSMALL(bytes_needed, payload_bytes, "Message is too small for this syscall!"); - - struct syscall_generic_write *payload = payload_data; - bytes_needed += payload->len * 2; - CHECK_TOOSMALL(bytes_needed, payload_bytes, "Message is too small for write buffer!"); - - return serial_com_write(serial_com, payload->data, payload->len); -} - -int -_syscall_handle_serial(syscall_context_t *ctx) -{ - switch(ctx->header->callid) { - case SYSCALL_SERIAL_COM_WRITE: - return s_syscall_serial_write(ctx->target.obj, ctx->bytes_left, ctx->payload); - default: - kprintf("syscall_serial: serial com object does not support syscall %i\n", ctx->header->callid); - return -EBADCALL; - } -} diff --git a/boot/boot.h b/boot/boot.h new file mode 100644 index 0000000..1fca074 --- /dev/null +++ b/boot/boot.h @@ -0,0 +1,19 @@ +#ifndef _JOVE_BOOT_H +#define _JOVE_BOOT_H 1 + +#include "hal/obj.h" + +struct kernel_module +{ + jove_obj_t *shmem; + char path[128]; +}; + +jove_owned_obj_t *boot_getmodule(const char *path); + +void cmdline_init(char *cmdline); +void cmdline_print(void); +const char *cmdline_getarg(const char *key); + + +#endif diff --git a/boot/cmdline.c b/boot/cmdline.c index 06a6169..13edf40 100644 --- a/boot/cmdline.c +++ b/boot/cmdline.c @@ -1,5 +1,5 @@ #include "config.h" -#include "cmdline.h" +#include "boot.h" #include <stddef.h> #include "lib/string.h" #include "lib/printf.h" diff --git a/boot/cmdline.h b/boot/cmdline.h deleted file mode 100644 index aa5da43..0000000 --- a/boot/cmdline.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _JOVE_BOOT_CMDLINE_H -#define _JOVE_BOOT_CMDLINE_H 1 - -void cmdline_init(char *cmdline); - -void cmdline_print(void); -const char *cmdline_getarg(const char *key); - -#endif diff --git a/boot/initrd.c b/boot/initrd.c deleted file mode 100644 index e998c08..0000000 --- a/boot/initrd.c +++ /dev/null @@ -1,98 +0,0 @@ -#include "initrd.h" -#include "arch/x86_64/hal/obj.h" -#include "proc/init.h" -#include "jove.h" -#include "lib/printf.h" -#include "lib/tar.h" -#include "lib/string.h" -#include "hal/obj.h" -#include "hal/memory.h" -#include "sys/objdir.h" - -extern uintptr_t _initrd_module; - -PAGEALIGN jove_objdir_t s_initrd_objdir = { 0 }; - -#define CHECK_IF_INITRD(obj) \ - if(obj_gettype(obj) != JOVE_OBJ_INITRD_FILE) { \ - reterr(EBADOBJ); \ - } - -const char* -initrd_file_name(jove_owned_obj_t *obj) -{ - CHECK_IF_INITRD(obj); - struct tar_header *file = obj_deref(obj); - return tar_filename(file); -} - -size_t -initrd_file_size(jove_owned_obj_t *obj) -{ - CHECK_IF_INITRD(obj); - struct tar_header *file = obj_deref(obj); - return tar_filesize(file); -} - -void* -initrd_file_data(jove_owned_obj_t *obj) -{ - CHECK_IF_INITRD(obj); - union tar_block *file = obj_deref(obj); - return &(file[1]); -} - -jove_owned_obj_t* -initrd_seek(jove_owned_obj_t *objdir, const char *path) -{ - if(obj_gettype(objdir) != JOVE_OBJ_OBJDIR) { - reterr(EBADOBJ); - } - for(size_t i = 0; i < OBJDIR_ENTRIES; i++) { - jove_owned_obj_t *file_obj = objdir_getlocal(objdir, i); - if(obj_gettype(file_obj) != JOVE_OBJ_INITRD_FILE) { - goto loop_continue; - } - const char *filepath = initrd_file_name(file_obj); - if(filepath == NULL) { - goto loop_continue; - } - - if(strncmp(path, filepath, strlen(filepath)+1) == 0) { - return file_obj; - } -loop_continue: - obj_release(file_obj); - } - - return NULL; -} - -void initrd_setup(void) -{ - kprintf("Loading initrd from bootloader:\n"); - { - jove_owned_obj_t *initrd_objdir_obj = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_INITRD_I); - obj_settype(initrd_objdir_obj, JOVE_OBJ_OBJDIR); - obj_setvalue(initrd_objdir_obj, (uintmax_t)&s_initrd_objdir); - - size_t initrd_files = 0; - union tar_block *block = phys_tovirt(_initrd_module); - for(;;) { - struct tar_header *header = &block->header; - if(*header->filename == 0) break; - - size_t file_size = tar_filesize(header); - kprintf("File: %s, Size: %i\n", tar_filename(header), file_size); - { - jove_owned_obj_t *initrd_file_obj = objdir_getlocal(initrd_objdir_obj, initrd_files++); - obj_settype(initrd_file_obj, JOVE_OBJ_INITRD_FILE); - obj_setvalue(initrd_file_obj, (uintmax_t)block); - obj_release(initrd_file_obj); - } - - block = &block[((file_size + 511) / 512) + 1]; - } - obj_release(initrd_objdir_obj); - } -} diff --git a/boot/initrd.h b/boot/initrd.h deleted file mode 100644 index c56b6f8..0000000 --- a/boot/initrd.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _JOVE_BOOT_INITRD_H -#define _JOVE_BOOT_INITRD_H 1 - -#include "hal/obj.h" - -const char *initrd_file_name(jove_owned_obj_t *obj); -size_t initrd_file_size(jove_owned_obj_t *obj); -void *initrd_file_data(jove_owned_obj_t *obj); - -jove_owned_obj_t *initrd_seek(jove_owned_obj_t *objdir, const char *name); - -void initrd_setup(void); - -#endif diff --git a/boot/limine/framebuffer.c b/boot/limine/framebuffer.c deleted file mode 100644 index a7ee04c..0000000 --- a/boot/limine/framebuffer.c +++ /dev/null @@ -1,82 +0,0 @@ -#include "arch/x86_64/hal/obj.h" -#include "jove.h" -#include "lib/printf.h" -#include "limine.h" -#include "proc/init.h" -#include "sys/objdir.h" -#include "hal/framebuffer.h" - -extern struct limine_framebuffer_response *_limine_framebuffers; - -#define CHECK_IF_FB(obj) \ - if(obj_gettype(obj) != JOVE_OBJ_FRAMEBUFFER) { \ - reterr(EBADOBJ); \ - } - -size_t -fb_width(jove_owned_obj_t *obj) -{ - CHECK_IF_FB(obj); - struct limine_framebuffer *fb = obj_deref(obj); - return fb->width; -} - -size_t -fb_height(jove_owned_obj_t *obj) -{ - CHECK_IF_FB(obj); - struct limine_framebuffer *fb = obj_deref(obj); - return fb->height; -} - -int -fb_blit(jove_owned_obj_t *obj, - uint32_t *data, - size_t x, size_t y, - size_t width, size_t height) -{ - CHECK_IF_FB(obj); - struct limine_framebuffer *fb = obj_deref(obj); - - uint32_t *fb_address = fb->address; - for(size_t oline = 0; oline < height; oline++) { - size_t line = oline + y; - uint32_t *line_data = &data[oline * width]; - for(size_t ocol = 0; ocol < width; ocol++) { - size_t col = ocol + x; - fb_address[line * (fb->pitch >> 2) + col] = line_data[ocol]; - } - } - return 0; -} - -void -fb_init() -{ - if(_limine_framebuffers->framebuffer_count == 0) { - return; - } - struct limine_framebuffer *fb = _limine_framebuffers->framebuffers[0]; - size_t fb_bytes = fb->width * fb->height * (fb->bpp / 8); - void *fb_virt = fb_remap((uintptr_t)fb->address, fb_bytes); - - //void *fb_virt = fb->address; - if(fb_virt == NULL) { - kprintf("Unable to remap framebuffer.\n"); - return; - } - - kprintf("framebuffer: phys address %p\n", (uintptr_t)fb->address); - kprintf("framebuffer: virt address %p\n", fb_virt); - kprintf("framebuffer: width %ipx\n", fb->width); - kprintf("framebuffer: height %ipx\n", fb->height); - kprintf("framebuffer: %i bpp\n", fb->bpp); - - fb->address = fb_virt; - { - jove_owned_obj_t *fb_obj = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_FRAMEBUFFER_I); - obj_settype(fb_obj, JOVE_OBJ_FRAMEBUFFER); - obj_setvalue(fb_obj, (uintptr_t)fb); - obj_release(fb_obj); - } -} diff --git a/boot/limine/memorymap.c b/boot/limine/memorymap.c index c558e75..7ce1da8 100644 --- a/boot/limine/memorymap.c +++ b/boot/limine/memorymap.c @@ -66,10 +66,11 @@ mem_setup_regions(void) region_new(region_obj, entry->base, entry->length / 0x1000); obj_release(region_obj); } - } - if(entry->type == LIMINE_MEMMAP_RESERVED | - entry->type == LIMINE_MEMMAP_ACPI_NVS | - entry->type == LIMINE_MEMMAP_ACPI_TABLES) + }else + if(entry->type == LIMINE_MEMMAP_RESERVED || + entry->type == LIMINE_MEMMAP_ACPI_NVS || + entry->type == LIMINE_MEMMAP_ACPI_TABLES || + entry->type == LIMINE_MEMMAP_FRAMEBUFFER) { intmax_t hw_pages = entry->length >> 12; uintptr_t base = entry->base; @@ -90,6 +91,8 @@ mem_setup_regions(void) hw_pages -= 4096; base += (4096ULL << 12); } + }else{ + klogf("Kmem %p : %p %s\n", entry->base, entry->length, limine_mmap_entry_type_str[entry->type]); } } } diff --git a/boot/limine/modules.c b/boot/limine/modules.c new file mode 100644 index 0000000..669883e --- /dev/null +++ b/boot/limine/modules.c @@ -0,0 +1,64 @@ +#include "boot/boot.h" +#include "limine.h" +#include "hal/obj.h" +#include "hal/memory.h" +#include "lib/printf.h" +#include "lib/string.h" +#include "proc/init.h" +#include "panic/panic.h" + +static jove_objdir_t s_kmodules_objdir; +extern struct limine_module_response *_limine_module_resp; + +static struct kernel_module s_modules[BOOT_MAX_MODULES]; + +jove_owned_obj_t* +boot_getmodule(const char *key) { + for(size_t i = 0; i < BOOT_MAX_MODULES; i++) { + if(strncmp(s_modules[i].path, key, 128) == 0) + return obj_take(s_modules[i].shmem); + } + errno = ENOTFOUND; + return NULL; +} + +void +mem_setup_modules(void) +{ + jove_owned_obj_t *modules_objdir = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_MODULES_I); + obj_settype(modules_objdir, JOVE_OBJ_OBJDIR); + obj_setvalue(modules_objdir, (uintptr_t)&s_kmodules_objdir); + jove_obj_t *modules_objdir_obj = obj_release(modules_objdir); + + if(_limine_module_resp == NULL) { + kpanic("Limine failed to provide modules.\n"); + } + + kprintf("%s: Modules provided by Limine:\n", __func__); + for(size_t i = 0; i < _limine_module_resp->module_count; i++) { + struct limine_file *module = _limine_module_resp->modules[i]; + if(i >= BOOT_MAX_MODULES) { + klogf("Maximum number of modules exceeded (%i). Some modules will be inaccessable\n", BOOT_MAX_MODULES); + return; + } + + klogf("%p File %s at %p size %x\n", module, module->path, module->address, module->size); + + physaddr_t module_base = phys_fromvirt((virtaddr_t)module->address); + size_t module_pages = (module->size + 0xFFF) / 0x1000; + if(module_pages > SHMEMORY_MAX_PAGES) { + klogf("Module exceeds length maximum (%i vs %i). Some data will be non-addressable\n", + module_pages, SHMEMORY_MAX_PAGES); + module_pages = 0xFFF; + } + + jove_owned_obj_t *module_shmem = objdir_getlocal(modules_objdir_obj, i); + obj_settype(module_shmem, JOVE_OBJ_SHMEMORY); + obj_setvalue(module_shmem, module_base | module_pages); + + s_modules[i] = (struct kernel_module) { + .shmem = obj_release(module_shmem) + }; + strncpy(128, s_modules[i].path, module->path); + } +} diff --git a/boot/limine/start.c b/boot/limine/start.c index 803c1de..17016ce 100644 --- a/boot/limine/start.c +++ b/boot/limine/start.c @@ -2,7 +2,7 @@ #include <stddef.h> #include "api/init.h" -#include "boot/cmdline.h" +#include "boot/boot.h" #include "limine.h" void _start(void); @@ -65,6 +65,7 @@ void *_kernel_physptr = NULL; void *_initrd_module = NULL; struct limine_framebuffer_response *_limine_framebuffers; struct limine_memmap_response *_limine_memmap_resp = NULL; +struct limine_module_response *_limine_module_resp = NULL; __attribute__((noreturn)) void @@ -72,14 +73,11 @@ _start(void) { _kernel_physptr = (void*)executable_address_req.response->physical_base; _limine_memmap_resp = memmap_req.response; + _limine_module_resp = module_req.response; _limine_framebuffers = framebuffer_request.response; extern struct init_payload _init_payload; _init_payload.rsdp = (void*)((uintptr_t)rsdp_request.response->address & 0xFFFFFFFF); - - if(module_req.response->module_count > 0) { - _initrd_module = module_req.response->modules[0]->address; - } cmdline_init(cmdline_req.response->cmdline); @@ -3,6 +3,7 @@ #define DEBUG_TOOLS +#define BOOT_MAX_MODULES 2 #define CMDLINE_MAX_ARGUMENTS 128 #define SMP_PROCESSORS_MAX 8 @@ -1,4 +1,6 @@ -DBGFLAGS := IPC +DBGFLAGS := SERIAL IPC + +CDIRS := boot lib hal proc sys api panic debug CFLAGS = \ -ffreestanding \ diff --git a/debug/debug.c b/debug/debug.c new file mode 100644 index 0000000..77d5ce7 --- /dev/null +++ b/debug/debug.c @@ -0,0 +1,11 @@ +#include "debug.h" +#include "lib/printf.h" + +bool _debug_has_output = false; + +void +debug_init() +{ + _debug_init_arch(); + kprintf("Debug console enabled\n"); +} diff --git a/debug/debug.h b/debug/debug.h new file mode 100644 index 0000000..13228b7 --- /dev/null +++ b/debug/debug.h @@ -0,0 +1,11 @@ +#ifndef _JOVE_DEBUG_H +#define _JOVE_DEBUG_H 1 + +#include <stdbool.h> + +extern bool _debug_has_output; + +void debug_init(void); +void _debug_init_arch(void); + +#endif diff --git a/hal/framebuffer.h b/hal/framebuffer.h deleted file mode 100644 index e070889..0000000 --- a/hal/framebuffer.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _JOVE_HAL_FRAMEBUFFER_H -#define _JOVE_HAL_FRAMEBUFFER_H 1 - -#include <stddef.h> -#include "hal/obj.h" - -size_t fb_width(jove_owned_obj_t *fb); -size_t fb_height(jove_owned_obj_t *fb); -int fb_blit(jove_owned_obj_t *obj, uint32_t *data, size_t x, size_t y, size_t width, size_t height); - -void *fb_remap(uintptr_t fb_address, size_t fb_size); -void fb_init(void); - -#endif diff --git a/hal/memory.h b/hal/memory.h index 9e799c0..a8fdc86 100644 --- a/hal/memory.h +++ b/hal/memory.h @@ -49,6 +49,7 @@ extern virtaddr_t *__syscall_stack_mapping; extern virtaddr_t *__interrupt_stack_mapping; void mem_setup_regions(void); +void mem_setup_modules(void); physaddr_t phys_fromvirt(virtaddr_t virt); void *phys_tovirt(physaddr_t phys); @@ -107,5 +108,7 @@ int pagedir_unmap_shmem_frame( jove_owned_obj_t *tgt, uintptr_t vptr); int shmem_new(jove_owned_obj_t *untyped_obj); +size_t shmem_numpages(jove_owned_obj_t *shmem_obj); +void *shmem_deref(jove_owned_obj_t *shmem_obj); #endif diff --git a/hal/shmem.c b/hal/shmem.c index 3785c2e..2928a1b 100644 --- a/hal/shmem.c +++ b/hal/shmem.c @@ -18,3 +18,15 @@ shmem_new(jove_owned_obj_t *untyped_obj) memset(untyped, 0, untyped->limit); return 0; } + +inline size_t +shmem_numpages(jove_owned_obj_t *shmem_obj) +{ + return obj_getvalue(shmem_obj) & JOVE_SMHEM_MAXPAGES; +} + +inline void* +shmem_deref(jove_owned_obj_t *shmem_obj) +{ + return phys_tovirt(obj_getvalue(shmem_obj) & ~JOVE_SMHEM_MAXPAGES); +} diff --git a/lib/string.c b/lib/string.c index 28436d5..f4d42fb 100644 --- a/lib/string.c +++ b/lib/string.c @@ -46,5 +46,16 @@ char *str_toupper(char *s, size_t n) int strncmp(const char *s1, const char *s2, size_t n) { - return memcmp(s1, s2, n); + size_t i = 0; + for(; s1[i] && s2[i] && i < n; i++) { + int diff = s1[i] - s2[i]; + if(diff) return diff; + } + return s1[i] - s2[i]; +} + +char *strncpy(size_t n, char *restrict s1, const char *restrict s2) +{ + for(size_t i = 0; s2[i] && i < n; i++) s1[i] = s2[i]; + return s1; } diff --git a/lib/string.h b/lib/string.h index bdcb0dd..1696032 100644 --- a/lib/string.h +++ b/lib/string.h @@ -12,5 +12,6 @@ char c_toupper(char c); char *str_toupper(char *s, size_t n); int strncmp(const char *s1, const char *s2, size_t n); +char *strncpy(size_t n, char *restrict s1, const char *restrict s2); #endif diff --git a/lib/virtterm.c b/lib/virtterm.c deleted file mode 100644 index ce759be..0000000 --- a/lib/virtterm.c +++ /dev/null @@ -1,128 +0,0 @@ -#include "virtterm.h" -#include "boot/cmdline.h" -#include "boot/initrd.h" -#include "hal/obj.h" -#include "proc/init.h" -#include "jove.h" -#include "hal/framebuffer.h" -#include "sys/objdir.h" -#include "lib/printf.h" -#include "lib/psf.h" -#include "lib/string.h" - -struct psf1_header *s_font = NULL; - -struct virtterm s_init_vtty = { 0 }; - -static void -vt_blit(struct virtterm *vtty, jove_owned_obj_t *fb, const uint8_t *glyph) -{ - uint32_t buffer[s_font->char_height << 3]; - size_t cursor_x = vtty->cursor_col * 9; - size_t cursor_y = vtty->cursor_row * s_font->char_height; - - for(size_t y = 0; y < s_font->char_height; y++) { - uint8_t mask = 1 << 7; - for(size_t x = 0; x < 8; x++) { - buffer[x + (y << 3)] = glyph[y] & mask ? vtty->cursor_fg : vtty->cursor_bg; - mask >>=1; - } - } - fb_blit(fb, buffer, cursor_x, cursor_y, 8, s_font->char_height); - vtty->cursor_col++; -} - -static void -vt_putc(struct virtterm *vtty, jove_owned_obj_t *fb, char c) -{ - const uint8_t *glyph = &s_font->bitmap[(size_t)c * s_font->char_height]; - - switch(c) { - case '\n': - vtty->cursor_col = 0; - vtty->cursor_row++; - break; - default: - vt_blit(vtty, fb, glyph); - break; - } - - if(vtty->cursor_col >= vtty->width) { - vtty->cursor_col = 0; - vtty->cursor_row++; - } - if(vtty->cursor_row >= vtty->height) { - vtty->cursor_row = 0; - } -} - -int -vt_write(jove_owned_obj_t *obj, const char *s, size_t n) -{ - if(obj_gettype(obj) != JOVE_OBJ_VIRTTERM) { - reterr(EBADOBJ); - } - - struct virtterm *vtty = obj_deref(obj); - jove_owned_obj_t *fb_obj = objdir_getlocal(_rootdir_obj, vtty->fb_obj); - if(obj_gettype(fb_obj) != JOVE_OBJ_FRAMEBUFFER) { - obj_release(fb_obj); - reterr(EBADOBJ); - } - - for(size_t i = 0; i < n; i++) { - vt_putc(vtty, fb_obj, s[i]); - } - - obj_release(fb_obj); - return 0; -} - -void -vt_init() -{ - const char *font_path = cmdline_getarg("font"); - if(font_path == NULL) { - kprintf("Kernel commandline is missing 'font' argument. VTT is disabled."); - return; - } - - jove_owned_obj_t *initrd_obj = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_INITRD_I); - if(obj_gettype(initrd_obj) != JOVE_OBJ_OBJDIR) { - kprintf("Initrd is not present. VTT is disabled.\n"); - obj_release(initrd_obj); - return; - } - - jove_owned_obj_t *file_obj = initrd_seek(initrd_obj, font_path); - if(file_obj != NULL) { - s_font = initrd_file_data(file_obj); - obj_release(file_obj); - } - - obj_release(initrd_obj); - - if(s_font == NULL) { - kprintf("Could not find file %s in initrd. VTT is disabled.\n", font_path); - return; - } - if(s_font->magic != PSF1_FONT_MAGIC) { - kprintf("Font '%s' does not match magic number! VTT is disabled.\n", font_path); - return; - } - - s_init_vtty.fb_obj = INIT_ROOTDIR_FRAMEBUFFER_I; - s_init_vtty.cursor_fg = 0x00FFFFFF; - - { - jove_owned_obj_t *fb_obj = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_FRAMEBUFFER_I); - s_init_vtty.width = fb_width(fb_obj) / 9; - s_init_vtty.height = fb_height(fb_obj) / s_font->char_height; - obj_release(fb_obj); - - jove_owned_obj_t *vt_obj = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_VIRTTERM_I); - obj_settype(vt_obj, JOVE_OBJ_VIRTTERM); - obj_setvalue(vt_obj, (uintmax_t)&s_init_vtty); - obj_release(vt_obj); - } -} diff --git a/lib/virtterm.h b/lib/virtterm.h deleted file mode 100644 index 08e22e9..0000000 --- a/lib/virtterm.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef _JOVE_LIB_VIRTTERM_H -#define _JOVE_LIB_VIRTTERM_H 1 - -#include <stddef.h> -#include "hal/obj.h" - -struct virtterm -{ - size_t fb_obj; - size_t cursor_col, cursor_row; - size_t width, height; - uint32_t cursor_fg, cursor_bg; -}; - -int vt_write(jove_owned_obj_t *obj, const char *s, size_t n); - -void vt_init(void); - -#endif diff --git a/proc/init.c b/proc/init.c index 130b10e..39f3ba9 100644 --- a/proc/init.c +++ b/proc/init.c @@ -8,10 +8,7 @@ objpath_part_t s_last_region = OBJDIR_ENTRIES-1; jove_owned_obj_t init_pop_alloc(void) { - jove_owned_obj_t *freemem_dir = objdir_trygetlocal(_rootdir_obj, INIT_ROOTDIR_FREEMEMORY_I); - if(freemem_dir == 0) { - kpanic("Untyped directory is locked!\n"); - } + jove_obj_t *freemem_dir = obj_release(objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_FREEMEMORY_I)); int cycles = 0; while(cycles++ < 512) { @@ -29,7 +26,6 @@ init_pop_alloc(void) } obj_release(region); - obj_release(freemem_dir); return frame; } kpanic("%s: Kernel is out of memory!\n", __func__); diff --git a/proc/process.c b/proc/process.c index f659c24..19f8074 100644 --- a/proc/process.c +++ b/proc/process.c @@ -125,13 +125,13 @@ pcb_getrootdir(pcb_t *pcb) } inline jove_owned_obj_t* -pcb_getpagedir(jove_owned_obj_t *rootdir_obj) +pcb_getpagedir(jove_obj_t *rootdir_obj) { return objdir_getlocal(rootdir_obj, PCB_ROOTDIR_PAGEDIR_I); } inline jove_owned_obj_t* -pcb_getself(jove_owned_obj_t *rootdir_obj) +pcb_getself(jove_obj_t *rootdir_obj) { return objdir_getlocal(rootdir_obj, PCB_ROOTDIR_SELF_I); } diff --git a/proc/process.h b/proc/process.h index f566ba4..24bd379 100644 --- a/proc/process.h +++ b/proc/process.h @@ -43,8 +43,8 @@ pcb_t *pcb_frompid(pid_t pid); pid_t pcb_getpid(pcb_t *pcb); jove_obj_t *pcb_getrootdir(pcb_t *pcb); -jove_owned_obj_t *pcb_getpagedir(jove_owned_obj_t *rootdir_obj); -jove_owned_obj_t *pcb_getself(jove_owned_obj_t *rootdir_obj); +jove_owned_obj_t *pcb_getpagedir(jove_obj_t *rootdir_obj); +jove_owned_obj_t *pcb_getself(jove_obj_t *rootdir_obj); struct port *pcb_getport(pcb_t *pcb); diff --git a/proc/scheduler.c b/proc/scheduler.c index ba00abc..a3c3071 100644 --- a/proc/scheduler.c +++ b/proc/scheduler.c @@ -18,16 +18,13 @@ static uintmax_t s_this_tick; static inline void s_scheduler_swap_pcb(processor_t *proc, pcb_t *current_pcb, pcb_t *target_pcb) { - jove_owned_obj_t *target_rootdir = obj_take(pcb_getrootdir(target_pcb)); + jove_obj_t *target_rootdir = pcb_getrootdir(target_pcb); jove_owned_obj_t *target_pcb_obj = pcb_getself(target_rootdir); jove_obj_t target_pagedir = objdir_peeklocal(target_rootdir, PCB_ROOTDIR_PAGEDIR_I); - obj_release(target_rootdir); - processor_setpcb(proc, target_pcb_obj); _scheduler_switch_pcb_arch(target_pcb); - scheduler_switch( pcb_getksp_ref(current_pcb), pcb_getksp(target_pcb), @@ -170,15 +167,8 @@ void scheduler_init(jove_owned_obj_t *pcb_obj, void *process_main) pcb_set_syscall_stack((pcb_t*)pcb_header, obj_getvalue(&syscall_stack)); pcb_set_interrupt_stack((pcb_t*)pcb_header, obj_getvalue(&interrupt_stack)); - kprintf("Syscall stack %p %p\n", *__syscall_stack_mapping, pcb_get_syscall_stack((pcb_t*)pcb_header)); - kprintf("Interrupt stack %p %p\n", *__interrupt_stack_mapping, pcb_get_interrupt_stack((pcb_t*)pcb_header)); - _scheduler_switch_pcb_arch((pcb_t*)pcb_header); - jove_owned_obj_t *pagedir_obj = pcb_getpagedir(_rootdir_obj); - void *pagedir = (void*)obj_getvalue(pagedir_obj); - obj_release(pagedir_obj); - pcb_map_syscall_stack((pcb_t*)pcb_header); pcb_map_interrupt_stack((pcb_t*)pcb_header); @@ -7,46 +7,41 @@ jove_perm_obj_t -link_traverse(jove_owned_obj_t *link, lockstack_t *lockstack) +link_traverse(jove_owned_obj_t *link) { jove_perm_obj_t perm_obj = { .obj = link, .permissions = JOVE_PERM_ALL }; + while(obj_gettype(perm_obj.obj) == JOVE_OBJ_LINK) { jove_link_obj_t *link = obj_deref(perm_obj.obj); perm_obj.permissions &= link_getperm(link); - perm_obj.obj = lockstack_push(lockstack, link_deref(link)); + + jove_owned_obj_t *linked_obj = link_deref(link); + obj_release(perm_obj.obj); + perm_obj.obj = linked_obj; } return perm_obj; } jove_perm_obj_t -link_try_traverse(jove_owned_obj_t *link, lockstack_t *lockstack) +link_traverse_objdir( + jove_obj_t *objdir, + size_t pathlen, + objpath_part_t *path) { - jove_perm_obj_t perm_obj = { .obj = link, .permissions = JOVE_PERM_ALL }; - while(perm_obj.obj != NULL && obj_gettype(perm_obj.obj) == JOVE_OBJ_LINK) { - jove_link_obj_t *link = obj_deref(perm_obj.obj); - perm_obj.permissions &= link_getperm(link); - perm_obj.obj = lockstack_push(lockstack, link_deref(link)); - } - return perm_obj; -} + jove_owned_obj_t *objdir_obj = obj_take(objdir); + jove_perm_obj_t perm_obj = link_traverse(objdir_obj); + obj_release(objdir_obj); -jove_perm_obj_t -link_try_traverse_objdir(jove_owned_obj_t *objdir, lockstack_t *lockstack, - size_t pathlen, objpath_part_t *path) -{ - /*Do a traversal through the passed objdir to get objdir permissions.*/ - jove_perm_obj_t perm_obj = link_try_traverse(objdir, lockstack); - if(perm_obj.obj == 0) return perm_obj; if(pathlen == 0) return perm_obj; - - /*Get the object pointed to by the head of the path. */ - perm_obj.obj = lockstack_push(lockstack, objdir_trygetlocal(perm_obj.obj, path[0])); - if(pathlen > 1) lockstack_pop(lockstack); /*Don't lock the directory we're traversing. */ - - /*Recurse through the remaining path, resolving as we go. */ - jove_perm_obj_t traverse_obj = link_try_traverse_objdir(perm_obj.obj, lockstack, pathlen - 1, &path[1]); - /*Mask permissions against the head object. */ + jove_owned_obj_t *child_obj = objdir_getlocal(obj_release(perm_obj.obj), path[0]); + perm_obj.obj = child_obj; + + jove_perm_obj_t traverse_obj = link_traverse_objdir(obj_release(child_obj), pathlen - 1, &path[1]); + if(traverse_obj.obj != child_obj) { + obj_release(perm_obj.obj); + } traverse_obj.permissions &= perm_obj.permissions; + return traverse_obj; } @@ -21,16 +21,10 @@ void link_lock(jove_link_obj_t *link); void link_unlock(jove_link_obj_t *link); jove_owned_obj_t *link_deref(jove_link_obj_t *link); -jove_owned_obj_t *link_try_deref(jove_link_obj_t *link); - -jove_perm_obj_t link_traverse(jove_owned_obj_t *link, lockstack_t *lockstack); -jove_perm_obj_t link_try_traverse(jove_owned_obj_t *link, lockstack_t *lockstack); - -/**Try to retrieve an object from the object directory, resolving each link as it's encountered. - * Permissions are preserved through traversal, meaning objects are limited by their - * objdir permissions.*/ -jove_perm_obj_t link_try_traverse_objdir(jove_owned_obj_t *objdir, - lockstack_t *lockstack, size_t pathlen, objpath_part_t *path); +jove_perm_obj_t link_traverse(jove_owned_obj_t *link); +jove_perm_obj_t link_traverse_objdir(jove_obj_t *objdir, + size_t pathlen, + objpath_part_t *path); jove_obj_t link_unlink(jove_owned_obj_t *link); int link_new(jove_owned_obj_t *target_obj, jove_owned_obj_t *untyped_obj, uint8_t permissions); diff --git a/sys/lockstack.c b/sys/lockstack.c index 7a419ac..00de774 100644 --- a/sys/lockstack.c +++ b/sys/lockstack.c @@ -23,8 +23,9 @@ lockstack_pop(lockstack_t *stack) void lockstack_popall(lockstack_t *stack) { - for(size_t i = 0; i < stack->depth; i++) + for(size_t i = 0; i < stack->depth; i++) { obj_release(stack->stack[i]); + } stack->depth = 0; } diff --git a/sys/objdir.c b/sys/objdir.c index 5b59ddc..df4b3eb 100644 --- a/sys/objdir.c +++ b/sys/objdir.c @@ -19,100 +19,83 @@ objdir_new(jove_owned_obj_t *untyped_obj) jove_obj_t objdir_peeklocal( - jove_owned_obj_t *objdir_obj, + jove_obj_t *objdir_obj, uint16_t entry) { - if(obj_gettype(objdir_obj) != JOVE_OBJ_OBJDIR) { + jove_owned_obj_t *objdir = obj_take(objdir_obj); + if(obj_gettype(objdir) != JOVE_OBJ_OBJDIR) { errno = EBADOBJ; + obj_release(objdir); return (jove_obj_t) { 0 }; } if(entry >= OBJDIR_ENTRIES) { errno = EBADPATH; + obj_release(objdir); return (jove_obj_t) { 0 }; } - jove_objdir_t *objtab = obj_deref(objdir_obj); - return objtab->entries[entry]; + jove_objdir_t *objtab = obj_deref(objdir); + jove_obj_t obj = objtab->entries[entry]; + obj_release(objdir); + return obj; } jove_owned_obj_t* objdir_getlocal( - jove_owned_obj_t *objdir_obj, + jove_obj_t *objdir_obj, uint16_t entry) { - if(obj_gettype(objdir_obj) != JOVE_OBJ_OBJDIR) { - reterr(EBADOBJ); - } - if(entry >= OBJDIR_ENTRIES) { - reterr(EBADPATH); - } - - jove_objdir_t *objtab = obj_deref(objdir_obj); - return obj_take(&objtab->entries[entry]); + jove_owned_obj_t *objdir = obj_take(objdir_obj); + jove_owned_obj_t *obj = objdir_getlocal_locked(objdir, entry); + obj_release(objdir); + return obj; } -jove_owned_obj_t* -objdir_trygetlocal( - jove_owned_obj_t *objdir_obj, - uint16_t entry) +jove_owned_obj_t *objdir_getlocal_locked(jove_owned_obj_t *objdir, objpath_part_t entry) { - if(obj_gettype(objdir_obj) != JOVE_OBJ_OBJDIR) { + if(obj_gettype(objdir) != JOVE_OBJ_OBJDIR) { + obj_release(objdir); reterr(EBADOBJ); } if(entry >= OBJDIR_ENTRIES) { + obj_release(objdir); reterr(EBADPATH); } - jove_objdir_t *objtab = obj_deref(objdir_obj); - return obj_trytake(&objtab->entries[entry]); + jove_objdir_t *objtab = obj_deref(objdir); + jove_owned_obj_t *obj = obj_take(&objtab->entries[entry]); + return obj; } jove_owned_obj_t* objdir_getobj( - jove_owned_obj_t *objdir_obj, + jove_obj_t *objdir_obj, const uint16_t *path, size_t path_len) { - errno = 0; - if(path_len == 0) { - return objdir_obj; - } - { - jove_owned_obj_t *child_objdir = objdir_getlocal(objdir_obj, path[0]); - if(child_objdir == 0) { - reterr(EBADPATH); - } + jove_owned_obj_t *objdir = obj_take(objdir_obj); + jove_owned_obj_t *obj = objdir_getobj_locked(objdir, path, path_len); + obj_release(objdir); + return obj; - jove_owned_obj_t *target_obj = objdir_getobj(child_objdir, path + 1, path_len - 1); - obj_release(child_objdir); - return target_obj; - } } -jove_owned_obj_t* -objdir_trygetobj( - jove_owned_obj_t *objdir_obj, - const uint16_t *path, - size_t path_len) +jove_owned_obj_t *objdir_getobj_locked(jove_owned_obj_t *objdir, + const objpath_part_t *path, + size_t path_len) { errno = 0; - if(path_len == 0) { - return objdir_obj; - } - { - jove_owned_obj_t *child_objdir = objdir_trygetlocal(objdir_obj, path[0]); - if(child_objdir == 0) { - return 0; - } + if(path_len == 0) return objdir; - jove_owned_obj_t *target_obj = objdir_trygetobj(child_objdir, path + 1, path_len - 1); - obj_release(child_objdir); - return target_obj; - } + jove_owned_obj_t *child_obj = objdir_getlocal_locked(objdir, path[0]); + obj_release(objdir); + + if(child_obj == NULL) return NULL; + return objdir_getobj_locked(child_obj, &path[1], path_len - 1); } bool -objdir_compare(jove_owned_obj_t *objdir_obj, objpath_part_t entry, jove_obj_t *obj) +objdir_compare(jove_obj_t *objdir_obj, objpath_part_t entry, jove_obj_t *obj) { jove_obj_t peekobj = objdir_peeklocal(objdir_obj, entry); return obj_compare(&peekobj, obj); diff --git a/sys/objdir.h b/sys/objdir.h index e86e582..4ef6d04 100644 --- a/sys/objdir.h +++ b/sys/objdir.h @@ -8,10 +8,9 @@ int objdir_new(jove_owned_obj_t *untyped_obj); /*Returns the n'th entry of the object directory passed. * If the passed object is not an objdir, returns NULL and sets errno to EBADOBJ. * If the passed entry index is out of bounds, returns NULL and sets errno to EOOB.*/ -jove_owned_obj_t *objdir_getlocal(jove_owned_obj_t *objdir_obj, uint16_t entry); -/*Same as objdir_getlocal except does not block if entry obj is taken.*/ -jove_owned_obj_t *objdir_trygetlocal(jove_owned_obj_t *objdir_obj, uint16_t entry); -jove_obj_t objdir_peeklocal(jove_owned_obj_t *objdir_obj, uint16_t entry); +jove_owned_obj_t *objdir_getlocal(jove_obj_t *objdir_obj, uint16_t entry); +jove_owned_obj_t *objdir_getlocal_locked(jove_owned_obj_t *objdir, objpath_part_t entry); +jove_obj_t objdir_peeklocal(jove_obj_t *objdir_obj, uint16_t entry); /*Recursively seeks through an object directory for an object following the passed * path variable. @@ -20,11 +19,12 @@ jove_obj_t objdir_peeklocal(jove_owned_obj_t *objdir_obj, uint16_t entry); * If any object excluding the object at the end of the path is not an objdir, * returns NULL and sets errno to EBADOBJ. * If any entry in the path is out of bounds, returns NULL and sets errno to EBADOBJ.*/ -jove_owned_obj_t *objdir_getobj(jove_owned_obj_t *objdir_obj, const uint16_t *path, size_t path_len); -/*Same as objdir_getobj but does not block if child objects are locked.*/ -jove_owned_obj_t *objdir_trygetobj(jove_owned_obj_t *objdir_obj, const uint16_t *path, size_t path_len); +jove_owned_obj_t *objdir_getobj(jove_obj_t *objdir_obj, const uint16_t *path, size_t path_len); +jove_owned_obj_t *objdir_getobj_locked(jove_owned_obj_t *objdir, + const objpath_part_t *path, + size_t path_len); -bool objdir_compare(jove_owned_obj_t *objdir_obj, objpath_part_t entry, jove_obj_t *obj); +bool objdir_compare(jove_obj_t *objdir_obj, objpath_part_t entry, jove_obj_t *obj); void objdir_swapobj(jove_owned_obj_t *a, jove_owned_obj_t *b); #endif diff --git a/sys/syscall.c b/sys/syscall.c index 7d43d66..30bd851 100644 --- a/sys/syscall.c +++ b/sys/syscall.c @@ -8,22 +8,6 @@ #include "sys/link.h" #include "sys/message.h" -int __syscall_generic_objpath(jove_owned_obj_t *objdir, size_t payload_bytes, void *payload_data, jove_owned_obj_t **retobj) -{ - size_t bytes_needed = sizeof(struct syscall_generic_objpath); - CHECK_TOOSMALL(bytes_needed, payload_bytes, - "Message too small for payload."); - struct syscall_generic_objpath *payload = payload_data; - - bytes_needed += payload->pathlen << 1; - CHECK_TOOSMALL(bytes_needed, payload_bytes, - "Message too small for object path."); - - errno = 0; - *retobj = objdir_getobj(objdir, payload->path, payload->pathlen); - return errno; -} - int _syscall_handle_generic(syscall_context_t *ctx) { @@ -41,9 +25,6 @@ static const syscall_handle_t s_syscall_handles[128] = { [JOVE_OBJ_SHMEMORY] = _syscall_handle_generic, [JOVE_OBJ_PCB] = _syscall_handle_pcb, [JOVE_OBJ_INT_HANDLE] = _syscall_handle_generic, - [JOVE_OBJ_INITRD_FILE] = _syscall_handle_initrd_file, - [JOVE_OBJ_FRAMEBUFFER] = _syscall_handle_generic, - [JOVE_OBJ_VIRTTERM] = _syscall_handle_vtt, [JOVE_OBJ_MESSAGE] = _syscall_handle_generic, [JOVE_OBJ_LINK] = _syscall_handle_generic, }; @@ -88,10 +69,9 @@ syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen) ctx.pcb = process_current(); pcb_t *pcb = obj_deref(ctx.pcb); - ctx.objdir = lockstack_push(&ctx.lockstack, obj_take(pcb_getrootdir(pcb))); - - ctx.message = link_try_traverse_objdir( - ctx.objdir, &ctx.lockstack, message_pathlen, message_path); + ctx.objdir = pcb_getrootdir(pcb); + ctx.message = link_traverse_objdir(ctx.objdir, message_pathlen, message_path); + lockstack_push(&ctx.lockstack, ctx.message.obj); if(ctx.message.obj == NULL) { klogf("Process %i failed to get message %P : %s\n", @@ -139,28 +119,26 @@ syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen) ctx.bytes_left = messagelen - bytes_needed; ctx.payload = (void*)((uintptr_t)header + bytes_needed); - ctx.target = link_try_traverse_objdir( - ctx.objdir, &ctx.lockstack, ctx.header->pathlen, ctx.header->path); + if(ctx.header->pathlen == 1) { + if(ctx.header->path[0] == PCB_ROOTDIR_SELF_I) { + ctx.target = (jove_perm_obj_t) { .permissions = 0xFF, .obj = ctx.pcb }; + } else if(ctx.header->path[0] == PCB_ROOTDIR_PAGEDIR_I) { + ctx.target = (jove_perm_obj_t) { .permissions = 0xFF, .obj = pagedir }; + } else { + ctx.target = link_traverse(objdir_getlocal(ctx.objdir, ctx.header->path[0])); + lockstack_push(&ctx.lockstack, ctx.target.obj); + } + }else{ + ctx.target = link_traverse_objdir(ctx.objdir, ctx.header->pathlen, ctx.header->path); + lockstack_push(&ctx.lockstack, ctx.target.obj); + } if(ctx.target.obj == 0) { - //Check if we're trying to reference objects we've already locked in this function. - //If we are, we should set it as the target regardless of lock, - //since we're the ones with the lock already. - if(ctx.header->pathlen == 1) { - if(ctx.header->path[0] == PCB_ROOTDIR_SELF_I) - ctx.target = (jove_perm_obj_t) { .permissions = 0xFF, .obj = ctx.pcb }; - else if(ctx.header->path[0] == PCB_ROOTDIR_PAGEDIR_I) - ctx.target = (jove_perm_obj_t) { .permissions = 0xFF, .obj = pagedir }; - else - goto fail_target_busy; - }else{ -fail_target_busy: - //Could not find payload target in pcb rootdir. - klogf("Process %i tried to call syscall with bad target path %P : %s\n", - pcb_getpid(pcb), header->path, header->pathlen, errstr(errno)); - sysret = -errno; - goto remap_return; - } + klogf("Process %i tried to call syscall with bad target path %P : %s\n", + pcb_getpid(pcb), header->path, header->pathlen, errstr(errno)); + sysret = -errno; + goto remap_return; + } sysret = _syscall_handle_switch(&ctx); diff --git a/sys/syscall.h b/sys/syscall.h index 946417c..15f3163 100644 --- a/sys/syscall.h +++ b/sys/syscall.h @@ -37,7 +37,7 @@ typedef struct syscall_state { lockstack_t lockstack; jove_owned_obj_t *pcb; - jove_owned_obj_t *objdir; + jove_obj_t *objdir; jove_perm_obj_t message; jove_perm_obj_t target; struct syscall_header *header; @@ -47,14 +47,11 @@ typedef struct syscall_state typedef int (*syscall_handle_t)(syscall_context_t*); -int __syscall_generic_objpath(jove_owned_obj_t *objdir, size_t bytes_left, void *payload_data, jove_owned_obj_t **retobj); - int _syscall_handle_switch(syscall_context_t *ctx); int _syscall_handle_generic(syscall_context_t *ctx); int _syscall_handle_arch(syscall_context_t *ctx); -int _syscall_handle_vtt(syscall_context_t *ctx); int _syscall_handle_objdir(syscall_context_t *ctx); int _syscall_handle_untyped(syscall_context_t *ctx); int _syscall_handle_pagedir(syscall_context_t *ctx); diff --git a/sys/syscall_initrd_file.c b/sys/syscall_initrd_file.c deleted file mode 100644 index 904039d..0000000 --- a/sys/syscall_initrd_file.c +++ /dev/null @@ -1,99 +0,0 @@ -#include "api/error.h" -#include "boot/initrd.h" -#include "lib/printf.h" -#include "sys/message.h" -#include "sys/syscall.h" -#include "lib/string.h" - -int -s_syscall_initrd_file_name( - jove_owned_obj_t *initrd_file, - jove_owned_obj_t *message, - void *message_data) -{ - const char *filename = initrd_file_name(initrd_file); - size_t filename_len = strlen(filename); - - size_t bytes_left = 0x1000; - size_t bytes_needed = filename_len + sizeof(struct syscall_initrd_file_name_ret); - - CHECK_TOOSMALL(bytes_needed, bytes_left, "Message is too small for file name."); - struct syscall_initrd_file_name_ret *payload = message_data; - - payload->len = filename_len; - memcpy(payload->c_str, filename, filename_len); - return 0; -} - -int -s_syscall_initrd_file_size(jove_owned_obj_t *initrd_file) -{ - return initrd_file_size(initrd_file); -} - -int -s_syscall_initrd_file_read( - jove_owned_obj_t *initrd_file, - jove_owned_obj_t *message, - void *message_data, - size_t bytes_left, - void *payload_data) -{ - //Ensure that the message payload could hold the required read payload. - size_t bytes_needed = sizeof(struct syscall_initrd_file_read); - CHECK_TOOSMALL(bytes_needed, bytes_left, - "Message is too small to hold read payload."); - - struct syscall_initrd_file_read *payload = payload_data; - bytes_needed = payload->read_size; - bytes_left = 0x1000; - - //Ensure that the message is big enough to hold the read file data. - CHECK_TOOSMALL(bytes_needed, bytes_left, - "Message is too small to hold read bytes."); - - size_t file_size = initrd_file_size(initrd_file); - char *file_data = initrd_file_data(initrd_file); - - //Ensure that the start index is within the file. - if(payload->start_index >= file_size) { - klogf("Start index exceeds file length! (%i > %i)\n", - payload->start_index, file_size); - return -EOOB; - } - - //Ensure that the read bounds is within the file. - if(payload->start_index + payload->read_size > file_size) { - klogf("Read bounds exceed file length! (%i+%i > %i)\n", - payload->start_index, payload->read_size, file_size); - return -ETOOBIG; - } - - memcpy(message_data, file_data + payload->start_index, payload->read_size); - return 0; -} - -int -_syscall_handle_initrd_file(syscall_context_t *ctx) -{ - switch(ctx->header->callid) { - case SYSCALL_INITRD_FILE_NAME: - if(ctx->target.permissions & SYSCALL_PERM_INITRD_FILE_NAME) - return s_syscall_initrd_file_name( - ctx->target.obj, ctx->message.obj, (void*)ctx->header); - return -EPERM; - - case SYSCALL_INITRD_FILE_SIZE: - if(ctx->target.permissions & SYSCALL_PERM_INITRD_FILE_SIZE) - return s_syscall_initrd_file_size(ctx->target.obj); - return -EPERM; - - case SYSCALL_INITRD_FILE_READ: - if(ctx->target.permissions & SYSCALL_PERM_INITRD_FILE_READ) - return s_syscall_initrd_file_read( - ctx->target.obj, ctx->message.obj, (void*)ctx->header, ctx->bytes_left, ctx->payload); - return -EPERM; - default: - return -EBADCALL; - } -} diff --git a/sys/syscall_objdir.c b/sys/syscall_objdir.c index 199cbab..8a17671 100644 --- a/sys/syscall_objdir.c +++ b/sys/syscall_objdir.c @@ -7,8 +7,8 @@ int s_syscall_objdir_objtype( - jove_owned_obj_t *objdir, - jove_owned_obj_t *target_dir, + jove_obj_t *objdir, + jove_obj_t *target_dir, size_t payload_size, void *payload_data) { @@ -27,36 +27,44 @@ s_syscall_objdir_objtype( } static int -s_syscall_objdir_swap(jove_owned_obj_t *target_obj, - lockstack_t *lockstack, - jove_owned_obj_t *rootdir, - size_t bytes_left, - void *payload_data) +s_syscall_objdir_swap(lockstack_t *lockstack, + jove_obj_t *rootdir, + size_t bytes_left, + void *payload_data) { + //Verify the message is big enough for the payload. size_t bytes_needed = sizeof(struct syscall_objdir_swap); CHECK_TOOSMALL(bytes_needed, bytes_left, "Message too small for payload."); + //Verify the message is big enough for the other path. struct syscall_objdir_swap *payload = payload_data; bytes_needed += payload->other_path_length * sizeof(objpath_part_t); CHECK_TOOSMALL(bytes_needed, bytes_left, "Message too small for other path."); - jove_owned_obj_t *obj_a = lockstack_push(lockstack, objdir_trygetlocal(target_obj, payload->index)); + //Verify the object pointed to in the entry exists. + jove_obj_t *target = lockstack_pop(lockstack); + jove_owned_obj_t *obj_a = lockstack_push(lockstack, objdir_getlocal(target, payload->index)); if(obj_a == NULL) { klogf("Getting local object %i failed : %s\n", payload->index, errstr(errno)); return -errno; } - jove_perm_obj_t objdir_b = link_try_traverse_objdir(rootdir, lockstack, - payload->other_path_length - 1, payload->other_path); + + //Verify the second object directory exists. + jove_perm_obj_t objdir_b = link_traverse_objdir(rootdir, payload->other_path_length - 1, payload->other_path); if(objdir_b.obj == NULL) { + obj_release(objdir_b.obj); klogf("Getting object %P failed : %s\n", payload->other_path, payload->other_path_length, errstr(errno)); return -errno; } - + + //Verify the second object directory has the correct permissions. CHECK_OBJPERM(objdir_b, SYSCALL_PERM_OBJDIR_SWAP_TGT, "Other object is missing permission"); + + //Verify the second object exists. jove_owned_obj_t *obj_b = lockstack_push(lockstack, - objdir_trygetlocal(objdir_b.obj, payload->other_path[payload->other_path_length-1])); + objdir_getlocal_locked(objdir_b.obj, payload->other_path[payload->other_path_length-1])); if(obj_b == NULL) { klogf("Getting object %P failed : %s\n", payload->other_path, payload->other_path_length, errstr(errno)); @@ -70,37 +78,46 @@ s_syscall_objdir_swap(jove_owned_obj_t *target_obj, static int s_syscall_objdir_link(jove_owned_obj_t *target_obj, lockstack_t *lockstack, - jove_owned_obj_t *rootdir_obj, + jove_obj_t *rootdir_obj, size_t bytes_left, void *payload_data) { + //Verify the message is big enough for the payload. size_t bytes_needed = sizeof(struct syscall_objdir_link); CHECK_TOOSMALL(bytes_needed, bytes_left, "Message too small for payload"); + //Verify the message is big enough for the second path. struct syscall_objdir_link *payload = payload_data; bytes_needed += payload->other_path_length * sizeof(objpath_part_t); CHECK_TOOSMALL(bytes_needed, bytes_left, "Message too small for other object"); - jove_owned_obj_t *link_obj = lockstack_push(lockstack, objdir_trygetlocal(target_obj, payload->index)); + //Verify the objdir index is a valid object. + jove_owned_obj_t *link_obj = lockstack_push(lockstack, objdir_getlocal_locked(target_obj, payload->index)); if(link_obj == NULL) { klogf("Getting local object %i failed : %s\n", payload->index, errstr(errno)); return -errno; } + + //Verify that the link object is infact a link object. CHECK_OBJTYPE(link_obj, JOVE_OBJ_LINK, "Local object is not a link object"); - jove_perm_obj_t dest_obj = link_try_traverse_objdir(rootdir_obj, lockstack, - payload->other_path_length, payload->other_path); + jove_perm_obj_t dest_obj = link_traverse_objdir(rootdir_obj, payload->other_path_length, payload->other_path); + lockstack_push(lockstack, dest_obj.obj); + + //Verify the destination path exists. if(dest_obj.obj == NULL) { klogf("Getting destination object %P failed : %s\n", payload->other_path, payload->other_path_length, errstr(errno)); return -errno; } + //Verify the destination path is empty. if(obj_gettype(dest_obj.obj) != JOVE_OBJ_NONE) { klogf("Destination object %P is not empty\n", payload->other_path, payload->other_path_length); return -EFULL; } + //Verify the destination path has the correct permissions. CHECK_OBJPERM(dest_obj, SYSCALL_PERM_OBJDIR_LINK_TGT, "Destination object is missing permissions"); return link_dup(link_obj, dest_obj.obj); } @@ -112,12 +129,12 @@ _syscall_handle_objdir(syscall_context_t *ctx) case SYSCALL_OBJDIR_OBJTYPE: if(ctx->target.permissions & SYSCALL_PERM_OBJDIR_OBJTYPE) return s_syscall_objdir_objtype( - ctx->objdir, ctx->target.obj, ctx->bytes_left, ctx->payload); + ctx->objdir, lockstack_pop(&ctx->lockstack), ctx->bytes_left, ctx->payload); return -EPERM; case SYSCALL_OBJDIR_SWAP: if(ctx->target.permissions & SYSCALL_PERM_OBJDIR_SWAP) - return s_syscall_objdir_swap(ctx->target.obj, + return s_syscall_objdir_swap( &ctx->lockstack, ctx->objdir, ctx->bytes_left, ctx->payload); return -EPERM; diff --git a/sys/syscall_pagedir.c b/sys/syscall_pagedir.c index 7b8f315..6e773bf 100644 --- a/sys/syscall_pagedir.c +++ b/sys/syscall_pagedir.c @@ -5,9 +5,9 @@ #include "syscall.h" static int -s_get_untyped( +s_syscall_pagedir_get_untyped( lockstack_t *lockstack, - jove_owned_obj_t *objdir, + jove_obj_t *objdir, jove_owned_obj_t *pml4, size_t payload_bytes, void *payload_data, @@ -20,7 +20,7 @@ s_get_untyped( struct syscall_pagedir_map *payload = payload_data; if(payload->virtual_address > 0xFFFF800000000000ULL) { kprintf("%s: Virtual address is above user limit.\n", __func__); - return EBADARG; + return -EBADARG; } bytes_needed += payload->untyped_pathlen << 1; @@ -28,12 +28,13 @@ s_get_untyped( "Message too small for untyped path."); errno = 0; - jove_perm_obj_t untyped = link_try_traverse_objdir( - objdir, lockstack, payload->untyped_pathlen, payload->untyped_path); + jove_perm_obj_t untyped = link_traverse_objdir(objdir, payload->untyped_pathlen, payload->untyped_path); + lockstack_push(lockstack, untyped.obj); - if(errno) { - kprintf("%s: Untyped obj failed for the reason: %s\n", __func__, errstr(errno)); - return errno; + if(untyped.obj == 0) { + klogf("Unable to get untyped object %P : %s\n", + payload->untyped_path, payload->untyped_pathlen, errstr(errno)); + return -errno; } CHECK_OBJTYPE(untyped.obj, JOVE_OBJ_UNTYPED, @@ -45,12 +46,11 @@ s_get_untyped( if((uintptr_t)untyped_data & 0xFFF) { kprintf("%s: Untyped object is not page aligned.\n", __func__); - return EALIGN; + return -EALIGN; } if(untyped_data->limit != 0x1000) { - kprintf("%s: Untyped object is not page sized. (expected 0x1000 got 0x%X)\n", __func__, - untyped_data->limit); - return EBADSIZE; + klogf("Untyped object is not page sized. (%x vs 1000)\n", untyped_data->limit); + return -EBADSIZE; } *untyped_ret = untyped; @@ -60,7 +60,7 @@ s_get_untyped( static int s_syscall_pagedir_unmap( lockstack_t *lockstack, - jove_owned_obj_t *objdir, + jove_obj_t *objdir, jove_owned_obj_t *pagedir, size_t payload_bytes, void *payload_data, @@ -80,8 +80,9 @@ s_syscall_pagedir_unmap( CHECK_TOOSMALL(bytes_needed, payload_bytes, "Message too small for none path"); - jove_perm_obj_t none = link_try_traverse_objdir( - objdir, lockstack, payload->none_pathlen, payload->none_path); + jove_perm_obj_t none = link_traverse_objdir( + objdir, payload->none_pathlen, payload->none_path); + lockstack_push(lockstack, none.obj); if(errno) { kprintf("%s: None obj retrieval failed for the reason: %s\n", @@ -98,13 +99,13 @@ s_syscall_pagedir_unmap( static int s_syscall_pagedir_map_frame( lockstack_t *lockstack, - jove_owned_obj_t *objdir, + jove_obj_t *objdir, jove_owned_obj_t *pagedir, size_t payload_bytes, void *payload_data) { jove_perm_obj_t untyped = { .obj = NULL, .permissions = 0 }; - int sysret = s_get_untyped(lockstack, objdir, pagedir, payload_bytes, payload_data, &untyped); + int sysret = s_syscall_pagedir_get_untyped(lockstack, objdir, pagedir, payload_bytes, payload_data, &untyped); if(sysret != 0) { return sysret; } @@ -121,13 +122,13 @@ s_syscall_pagedir_map_frame( static int s_syscall_pagedir_map_table( lockstack_t *lockstack, - jove_owned_obj_t *objdir, + jove_obj_t *objdir, jove_owned_obj_t *pagedir, size_t payload_bytes, void *payload_data) { jove_perm_obj_t untyped = { .obj = NULL, .permissions = 0 }; - int sysret = s_get_untyped(lockstack, objdir, pagedir, payload_bytes, payload_data, &untyped); + int sysret = s_syscall_pagedir_get_untyped(lockstack, objdir, pagedir, payload_bytes, payload_data, &untyped); if(sysret != 0) { return sysret; } @@ -144,7 +145,7 @@ s_syscall_pagedir_map_table( static int s_syscall_pagedir_map_shmem( lockstack_t *lockstack, - jove_owned_obj_t *objdir, + jove_obj_t *objdir, jove_owned_obj_t *pagedir, size_t payload_bytes, void *payload_data) @@ -163,10 +164,10 @@ s_syscall_pagedir_map_shmem( CHECK_TOOSMALL(bytes_needed, payload_bytes, "Message too small for shared memory path."); - errno = 0; - jove_perm_obj_t shmem = link_try_traverse_objdir( - objdir, lockstack, payload->shmem_pathlen, payload->shmem_path); - if(errno) { + jove_perm_obj_t shmem = link_traverse_objdir(objdir, payload->shmem_pathlen, payload->shmem_path); + lockstack_push(lockstack, shmem.obj); + + if(shmem.obj == NULL) { klogf("Unable to retrieve shared memory object %P : %s\n", payload->shmem_path, payload->shmem_pathlen, errstr(errno)); return errno; @@ -191,7 +192,7 @@ s_syscall_pagedir_map_shmem( static int s_syscall_pagedir_unmap_frame( lockstack_t *lockstack, - jove_owned_obj_t *objdir, + jove_obj_t *objdir, jove_owned_obj_t *pagedir, size_t payload_bytes, void *payload_data) @@ -208,7 +209,7 @@ s_syscall_pagedir_unmap_frame( static int s_syscall_pagedir_unmap_table( lockstack_t *lockstack, - jove_owned_obj_t *objdir, + jove_obj_t *objdir, jove_owned_obj_t *pagedir, size_t payload_bytes, void *payload_data) @@ -227,7 +228,7 @@ _syscall_handle_pagedir(syscall_context_t *ctx) { lockstack_t *lockstack = &ctx->lockstack; struct syscall_header *header = ctx->header; - jove_owned_obj_t *objdir = ctx->objdir; + jove_obj_t *objdir = ctx->objdir; jove_perm_obj_t *target = &ctx->target; size_t bytes_left = ctx->bytes_left; void *payload = ctx->payload; diff --git a/sys/syscall_pcb.c b/sys/syscall_pcb.c index 3aeb22b..7a6d4e3 100644 --- a/sys/syscall_pcb.c +++ b/sys/syscall_pcb.c @@ -12,7 +12,7 @@ s_syscall_pcb_yield(jove_owned_obj_t *pcb_obj, size_t bytes_left, void *payload_data) { - //Validate that message is big enough for payload + //Verify message is big enough for payload size_t bytes_needed = sizeof(pid_t); CHECK_TOOSMALL(bytes_needed, bytes_left, "Message too small for payload"); @@ -26,40 +26,43 @@ s_syscall_pcb_yield(jove_owned_obj_t *pcb_obj, int s_syscall_pcb_send(jove_owned_obj_t *pcb_obj, lockstack_t *lockstack, - jove_owned_obj_t *objdir_obj, + jove_obj_t *objdir_obj, size_t bytes_left, void *payload_data) { - //Validate that message is big enough for payload. + //Verify message is big enough for payload. size_t bytes_needed = sizeof(struct syscall_pcb_send); CHECK_TOOSMALL(bytes_needed, bytes_left, "Message too small for payload"); struct syscall_pcb_send *payload = payload_data; - //Validate that message is big enough for payload object path. + //Verify message is big enough for payload object path. bytes_needed += payload->send_path_length; CHECK_TOOSMALL(bytes_needed, bytes_left, "Message too small for subject path"); - //Validate that subject object path is not the root directory. + //Verify subject object path is not the root directory. if(payload->send_path_length == 0) { kprintf("%s: Unable to send root directory\n", __func__); return -EBADPATH; } - //Validate that the subject objdir path is valid. - jove_perm_obj_t subject_objdir = link_try_traverse_objdir( - objdir_obj, lockstack, payload->send_path_length - 1, payload->send_path); - if(errno) { + //Verify the subject objdir path is valid. + jove_perm_obj_t subject_objdir = link_traverse_objdir(objdir_obj, payload->send_path_length - 1, payload->send_path); + + if(subject_objdir.obj == NULL) { klogf("Unable to get subject %P objdir : %s\n", payload->send_path, payload->send_path_length, errstr(errno)); + obj_release(subject_objdir.obj); return -errno; } - //Validate that the currently running PCB has mutate permissions for this objdir. + //Verify the currently running PCB has mutate permissions for this objdir. CHECK_OBJPERM(subject_objdir, SYSCALL_PERM_PCB_SEND_OBJDIR, "Subject objdir does not permit send"); - //Validate that the subject exists in the subject objdir. - jove_owned_obj_t *subject = objdir_trygetlocal(subject_objdir.obj, - payload->send_path[payload->send_path_length-1]); + //Verify the subject exists in the subject objdir. + jove_owned_obj_t *subject = objdir_getlocal( + obj_release(subject_objdir.obj), payload->send_path[payload->send_path_length-1]); + lockstack_push(lockstack, subject); + if(subject == 0) { klogf("Unable to get subject %P object : %s\n", payload->send_path, payload->send_path_length, errstr(errno)); @@ -73,29 +76,30 @@ s_syscall_pcb_send(jove_owned_obj_t *pcb_obj, int s_syscall_pcb_recv(jove_owned_obj_t *pcb_obj, lockstack_t *lockstack, - jove_owned_obj_t *objdir_obj, + jove_obj_t *objdir_obj, size_t bytes_left, void *payload_data) { - //Validate that the message is big enough for the payload. + //Verify the message is big enough for the payload. size_t bytes_needed = sizeof(struct syscall_pcb_recv); CHECK_TOOSMALL(bytes_needed, bytes_left, "Message too small for payload"); struct syscall_pcb_recv *payload = payload_data; - //Validate that the message is big enough for the payload object. + //Verify the message is big enough for the payload object. bytes_needed += payload->recv_path_length * sizeof(objpath_part_t); CHECK_TOOSMALL(bytes_needed, bytes_left, "Message too small for destination path"); - //Validate that the destination object exists. - jove_perm_obj_t destination = link_try_traverse_objdir( - objdir_obj, lockstack, payload->recv_path_length, payload->recv_path); + //Verify the destination object exists. + jove_perm_obj_t destination = link_traverse_objdir(objdir_obj, payload->recv_path_length, payload->recv_path); + lockstack_push(lockstack, destination.obj); + if(errno) { klogf("Unable to get destination %P : %s\n", payload->recv_path, payload->recv_path_length, errstr(errno)); return -errno; } - //Validate that the destination path is JOVE_OBJ_NONE and that the object has recieve permissions. + //Verify the destination path is JOVE_OBJ_NONE and that the object has recieve permissions. CHECK_OBJTYPE(destination.obj, JOVE_OBJ_NONE, "Destination object is occupied"); CHECK_OBJPERM(destination, SYSCALL_PERM_PCB_RECV_DST, "Destination object does not permit recv."); @@ -106,52 +110,55 @@ s_syscall_pcb_recv(jove_owned_obj_t *pcb_obj, int s_syscall_pcb_swap(jove_owned_obj_t *pcb_obj, lockstack_t *lockstack, - jove_owned_obj_t *objdir_obj, + jove_obj_t *objdir_obj, size_t bytes_left, void *payload_data) { - //Validate that the message is big enough for payload. + //Verify the message is big enough for payload. size_t bytes_needed = sizeof(struct syscall_pcb_recv); CHECK_TOOSMALL(bytes_needed, bytes_left, "Message too small for payload"); struct syscall_pcb_swap *payload = payload_data; - //Validate that the message is big enough for the subject path. + //Verify the message is big enough for the subject path. bytes_needed += payload->swap_path_length * sizeof(objpath_part_t); CHECK_TOOSMALL(bytes_needed, bytes_left, "Message too small for swap path"); - //Validate that the subject is not the rootdir. + //Verify the subject is not the rootdir. if(payload->swap_path_length == 0) { kprintf("%s: Unable to swap the root directory\n", __func__); return -EBADPATH; } - //Validate that the subject objdir exists. - jove_perm_obj_t subject_objdir = link_try_traverse_objdir( - objdir_obj, lockstack, payload->swap_path_length - 1, payload->swap_path); - if(errno) { + //Verify the subject objdir exists. + jove_perm_obj_t subject_objdir = link_traverse_objdir(objdir_obj, payload->swap_path_length - 1, payload->swap_path); + + if(subject_objdir.obj == NULL) { klogf("Unable to get subject %P objdir : %s\n", payload->swap_path, payload->swap_path_length, errstr(errno)); + obj_release(subject_objdir.obj); return -errno; } - //Validate that the subject objdir has send permissions. + //Verify the subject objdir has send permissions. CHECK_OBJPERM(subject_objdir, SYSCALL_PERM_PCB_SEND_OBJDIR, "Subject objdir does not permit send"); - //Validate that the subject object exists. - jove_owned_obj_t *subject = objdir_trygetlocal(subject_objdir.obj, - payload->swap_path[payload->swap_path_length-1]); + //Verify the subject object exists. + jove_owned_obj_t *subject = objdir_getlocal( + obj_release(subject_objdir.obj), payload->swap_path[payload->swap_path_length-1]); + lockstack_push(lockstack, subject); + if(subject == 0) { klogf("Unable to get subject %P object : %s\n", payload->swap_path, payload->swap_path_length, errstr(errno)); return -errno; } - //Validate that the target PCB exists. + //Verify the target PCB exists. if(pcb_frompid(payload->swap_target) == 0) { klogf("Swap PCB target %i does not exist\n", payload->swap_target); return -EBADPROC; } - //Validate that the message was sent before timeout. + //Verify the message was sent before timeout. int send_result = pcb_send( obj_deref(pcb_obj), payload->swap_target, subject, payload->send_timeout); if(send_result < 0) { @@ -159,7 +166,7 @@ s_syscall_pcb_swap(jove_owned_obj_t *pcb_obj, return send_result; } - //Validate that a message was recieved before timeout. + //Verify a message was recieved before timeout. int recv_result = pcb_recv( obj_deref(pcb_obj), payload->swap_target, subject, payload->recv_timeout); return recv_result; @@ -168,7 +175,7 @@ s_syscall_pcb_swap(jove_owned_obj_t *pcb_obj, int s_syscall_pcb_stack(jove_owned_obj_t *pcb_obj, lockstack_t *lockstack, - jove_owned_obj_t *rootdir, + jove_obj_t *rootdir, size_t bytes_left, void *payload_data) { @@ -181,8 +188,9 @@ s_syscall_pcb_stack(jove_owned_obj_t *pcb_obj, bytes_needed += sizeof(objpath_part_t) * payload->stack_path_length; CHECK_TOOSMALL(bytes_needed, bytes_left, "Message too small for untyped path"); - jove_perm_obj_t untyped = link_try_traverse_objdir(rootdir, lockstack, - payload->stack_path_length, payload->stack_path); + jove_perm_obj_t untyped = link_traverse_objdir(rootdir, payload->stack_path_length, payload->stack_path); + lockstack_push(lockstack, untyped.obj); + //Verify the untyped object exists. if(untyped.obj == NULL) { klogf("Unable to get untyped %P : %s\n", diff --git a/sys/syscall_region.c b/sys/syscall_region.c index 959d615..dc81634 100644 --- a/sys/syscall_region.c +++ b/sys/syscall_region.c @@ -7,7 +7,7 @@ static int s_syscall_region_alloc(jove_owned_obj_t *region_obj, - jove_owned_obj_t *objdir_obj, + jove_obj_t *objdir_obj, lockstack_t *lockstack, size_t bytes_left, void *payload_data) @@ -20,8 +20,9 @@ s_syscall_region_alloc(jove_owned_obj_t *region_obj, CHECK_TOOSMALL(bytes_needed, bytes_left, "Message too small for subject path"); - jove_perm_obj_t subject = link_try_traverse_objdir( - objdir_obj, lockstack, payload->dest_pathlen, payload->dest_path); + jove_perm_obj_t subject = link_traverse_objdir(objdir_obj, payload->dest_pathlen, payload->dest_path); + lockstack_push(lockstack, subject.obj); + CHECK_OBJEXISTS(subject.obj, "Destination path is bad."); CHECK_OBJPERM(subject, SYSCALL_PERM_REGION_ALLOC_TGT, "Destination path does not have correct permissions."); CHECK_OBJTYPE(subject.obj, JOVE_OBJ_NONE, "Destination object is not JOVE_OBJ_NONE"); diff --git a/sys/syscall_untyped.c b/sys/syscall_untyped.c index c64dea1..cc6b676 100644 --- a/sys/syscall_untyped.c +++ b/sys/syscall_untyped.c @@ -12,7 +12,7 @@ static int s_syscall_untyped_split( lockstack_t *lockstack, - jove_owned_obj_t *objdir, + jove_obj_t *objdir, jove_owned_obj_t *target_obj, size_t payload_bytes, void *payload_data) @@ -24,9 +24,10 @@ s_syscall_untyped_split( bytes_needed += payload->dest_pathlen * 2; CHECK_TOOSMALL(bytes_needed, payload_bytes, "Message is too small for destination path!"); - jove_perm_obj_t dest = link_try_traverse_objdir( - objdir, lockstack, payload->dest_pathlen, payload->dest_path); - if(errno) { + jove_perm_obj_t dest = link_traverse_objdir(objdir, payload->dest_pathlen, payload->dest_path); + lockstack_push(lockstack, dest.obj); + + if(dest.obj == NULL) { klogf("Unable to get destination object %P: %s\n", payload->dest_path, payload->dest_pathlen, errstr(errno)); return errno; @@ -45,7 +46,7 @@ s_syscall_untyped_split( static int s_syscall_untyped_merge( lockstack_t *lockstack, - jove_owned_obj_t *objdir, + jove_obj_t *objdir, jove_owned_obj_t *target_obj, size_t payload_bytes, void *payload_data) @@ -57,9 +58,10 @@ s_syscall_untyped_merge( bytes_needed += payload->pathlen * 2; CHECK_TOOSMALL(bytes_needed, payload_bytes, "Message is too small for second path!"); - jove_perm_obj_t untyped = link_try_traverse_objdir( - objdir, lockstack, payload->pathlen, payload->path); - if(errno) { + jove_perm_obj_t untyped = link_traverse_objdir(objdir, payload->pathlen, payload->path); + lockstack_push(lockstack, untyped.obj); + + if(untyped.obj == NULL) { klogf("Unable to retrieve untyped object %P : %s\n", payload->path, payload->pathlen, errstr(errno)); return errno; @@ -81,21 +83,22 @@ s_syscall_untyped_merge( int s_syscall_untyped_retype_pcb(jove_owned_obj_t *untyped_obj, lockstack_t *lockstack, - jove_owned_obj_t *rootdir, + jove_obj_t *rootdir, struct syscall_header *header) { jove_untyped_t *untyped = obj_deref(untyped_obj); CHECK_TOOSMALL(PCB_MINSIZE, untyped->limit, "Untyped object too small for PCB"); - jove_perm_obj_t objdir_obj = link_try_traverse_objdir( - rootdir, lockstack, header->pathlen - 1, header->path); - if(errno) { - klogf("Unable to retrieve parent objdir at %P\n", - header->path, header->pathlen - 1); + jove_perm_obj_t objdir_obj = link_traverse_objdir(rootdir, header->pathlen - 1, header->path); + + if(objdir_obj.obj == NULL) { + klogf("Unable to retrieve parent objdir at %P : %s\n", + header->path, header->pathlen - 1, errstr(errno)); + obj_release(objdir_obj.obj); return -errno; } CHECK_OBJPERM(objdir_obj, JOVE_PERM_ALL, "New PCB needs full access to it's root objdir!"); - if(!objdir_compare(objdir_obj.obj, PCB_ROOTDIR_SELF_I, obj_asunowned(untyped_obj))) { + if(!objdir_compare(obj_release(objdir_obj.obj), PCB_ROOTDIR_SELF_I, obj_asunowned(untyped_obj))) { klogf("Untyped is not in objdir entry %i\n", PCB_ROOTDIR_SELF_I); return -EBADPATH; } diff --git a/sys/syscall_vtt.c b/sys/syscall_vtt.c deleted file mode 100644 index dad05ba..0000000 --- a/sys/syscall_vtt.c +++ /dev/null @@ -1,33 +0,0 @@ -#include "jove.h" -#include "lib/printf.h" -#include "lib/virtterm.h" -#include "syscall.h" - -static int -s_syscall_vtt_write( - jove_owned_obj_t *vtt, - size_t payload_bytes, - void *payload_data) -{ - size_t bytes_needed = sizeof(struct syscall_generic_write); - CHECK_TOOSMALL(bytes_needed, payload_bytes, "Message is too small for this syscall!"); - - struct syscall_generic_write *payload = payload_data; - bytes_needed += payload->len * 2; - CHECK_TOOSMALL(bytes_needed, payload_bytes, "Message is too small for write buffer!"); - - return vt_write(vtt, payload->data, payload->len); -} - -int -_syscall_handle_vtt(syscall_context_t *ctx) -{ - - switch(ctx->header->callid) { - case SYSCALL_VTT_WRITE: - return s_syscall_vtt_write(ctx->target.obj, ctx->bytes_left, ctx->payload); - default: - klogf("vtt object does not support syscall %i\n", ctx->header->callid); - return -EBADCALL; - } -} |
