From 858a52c06a4615bd58a6a906333f2ad707d41c0a Mon Sep 17 00:00:00 2001 From: Jon Santmyer Date: Tue, 19 Aug 2025 15:04:04 -0400 Subject: usermode pager --- apps/init/Makefile | 3 +- apps/init/arch/x86_64/link.ld | 10 ++++ apps/init/arch/x86_64/paging.c | 109 +++++++++++++++++++++++++++++++++++++++++ apps/init/arch/x86_64/start.c | 11 +++++ apps/init/main.c | 77 ++++------------------------- apps/init/memory.h | 4 ++ apps/init/x86_64.ld | 10 ---- 7 files changed, 146 insertions(+), 78 deletions(-) create mode 100644 apps/init/arch/x86_64/link.ld create mode 100644 apps/init/arch/x86_64/paging.c create mode 100644 apps/init/arch/x86_64/start.c delete mode 100644 apps/init/x86_64.ld (limited to 'apps/init') diff --git a/apps/init/Makefile b/apps/init/Makefile index 642ca38..1834d0b 100644 --- a/apps/init/Makefile +++ b/apps/init/Makefile @@ -1,11 +1,12 @@ include $(CONFIG) CFILES := $(wildcard *.c) +CFILES += $(wildcard arch/$(TARGET_MACHINE)/*.c) OFILES := $(patsubst %.c,%.o,$(CFILES)) OFILES += $(STATICLIBS) CFLAGS := -ffreestanding -nostdlib -g -LDFLAGS := -T $(TARGET_MACHINE).ld +LDFLAGS := -T arch/$(TARGET_MACHINE)/link.ld OCFLAGS := -O binary \ --set-section-flags .bss=alloc,load,contents diff --git a/apps/init/arch/x86_64/link.ld b/apps/init/arch/x86_64/link.ld new file mode 100644 index 0000000..45b08f5 --- /dev/null +++ b/apps/init/arch/x86_64/link.ld @@ -0,0 +1,10 @@ +OUTPUT_ARCH(i386:x86-64) + +PAGESIZE = CONSTANT(MAXPAGESIZE); + +SECTIONS +{ + . = 0x1000; + .text BLOCK(PAGESIZE) : ALIGN(PAGESIZE) { *(.text.start) *(.text) *(.rodata) } + .data BLOCK(PAGESIZE) : ALIGN(PAGESIZE) { *(.data) *(.bss) } +} diff --git a/apps/init/arch/x86_64/paging.c b/apps/init/arch/x86_64/paging.c new file mode 100644 index 0000000..6c1c386 --- /dev/null +++ b/apps/init/arch/x86_64/paging.c @@ -0,0 +1,109 @@ +#include "../../memory.h" +#include "jove/object-dir.h" +#include "jove/jove.h" +#include +#include + +KernelObjectPageMap init_pagemap; +unsigned d_cache[3] = { -1, -1, -1 }; +uintptr_t vptr_cache = 0; + +KernelObjectUntyped work_page; + +#define PMLI_SHL(d) (((4 - d) * 9) + 3) +#define PMLI_DL(v, d) ((v >> PMLI_SHL(d)) % 512) + +uint64_t +pager_write_path(uintptr_t vptr, uint8_t depth) +{ + uint64_t r = 0; + if(depth >= 4) return -1; + + uint16_t *path = (uint16_t*)&r; + for(uint8_t i = 0; i < depth; i++) path[i] = PMLI_DL(vptr, i); + return r; +} + +bool +pager_depth_exists(uintptr_t vptr, uint8_t depth) +{ + uint64_t path = pager_write_path(vptr, depth); + if(path == -1) return false; + + return jove_pagemap_exists(&init_pagemap, depth, (uint16_t*)&path); +} +/* Places new page in work_page. */ +JoveError +pager_alloc_page_untyped(void) +{ + uint8_t lastmemb = jove_objdir_lastmemb(&untypedDirectory); + if(jove_errno) { + JoveError err = jove_errno; + jove_errno = EJOVE_OK; + return err; + } + + KernelObjectUntyped last_untyped; + _jove_alloc_untyped_inplace(&last_untyped, &untypedDirectory, lastmemb); + + if(jove_untyped_size(&last_untyped) == 0x1000) { + jove_objdir_move(&untypedDirectory, lastmemb, &__rootdir, work_page.typed.membi); + return EJOVE_OK; + } + + return jove_untyped_split_inplace(&last_untyped, 0x1000, &work_page); +} + +JoveError +pager_ensure_at_depth(uint8_t depth, uint16_t *path) +{ + int exists = jove_pagemap_exists(&init_pagemap, depth, path); + if(exists) { + return EJOVE_OK; + } + + JoveError pagealloc_err = pager_alloc_page_untyped(); + if(pagealloc_err) { + jove_kprintf("Failed to allocate page with error %i\n", pagealloc_err); + return pagealloc_err; + } + return jove_pagemap_map(&init_pagemap, depth, path, &work_page); +} + +#define PAGER_CACHE_ENSURE_DEPTH(path_seg, d) \ + if(path_seg[d] != d_cache[d]) { \ + JoveError d_err = pager_ensure_at_depth(d, path_seg); \ + if(d_err) return d_err; \ + d_cache[d] = path_seg[d]; \ + } + +JoveError +pager_ensure(uintptr_t vptr) +{ + uint64_t path = pager_write_path(vptr, 3); + if(path == -1) return EJOVE_BADARG; + + vptr &= ~0xFFFULL; + uint16_t *path_seg = (uint16_t*)&path; + jove_kprintf("%x:%x:%x:%x\n", path_seg[0], path_seg[1], path_seg[2], path_seg[3]); + + PAGER_CACHE_ENSURE_DEPTH(path_seg, 0); + PAGER_CACHE_ENSURE_DEPTH(path_seg, 1); + PAGER_CACHE_ENSURE_DEPTH(path_seg, 2); + if(vptr != vptr_cache) { + return pager_ensure_at_depth(3, path_seg); + } + return EJOVE_OK; +} + +void +pager_setup(void) +{ + _jove_alloc_objdir_inplace(&untypedDirectory, &__rootdir, INIT_OBJECT_UNTYPED_DIR); + _jove_alloc_pagemap_inplace(&init_pagemap, &__rootdir, INIT_OBJECT_PAGEMAP); + + size_t lastfree = jove_objdir_lastmemb(&__rootdir) + 1; + _jove_alloc_untyped_inplace(&work_page, &__rootdir, lastfree++); + + pager_ensure(0x00000000F0000000); +} diff --git a/apps/init/arch/x86_64/start.c b/apps/init/arch/x86_64/start.c new file mode 100644 index 0000000..8329523 --- /dev/null +++ b/apps/init/arch/x86_64/start.c @@ -0,0 +1,11 @@ +extern void main(void*); + +__attribute__((section(".text.start"))) +__attribute__((naked)) +void +_start(void) +{ + __asm__ volatile("\ + popq %%rdi; \ + jmp main"::); +} diff --git a/apps/init/main.c b/apps/init/main.c index c8dabdf..17b825e 100644 --- a/apps/init/main.c +++ b/apps/init/main.c @@ -4,11 +4,12 @@ #include #include #include -#include + +#include "memory.h" /**This program acts as a memory and process server.*/ -#define INIT_HEAP_START_BYTES 4096 +#define INIT_HEAP_START_BYTES 8192 __attribute__((section(".bss.heap"))) uint8_t init_heap[INIT_HEAP_START_BYTES]; size_t init_heap_start = (uintptr_t)init_heap; @@ -28,76 +29,18 @@ init_bumpalloc(size_t bytes) return r; } -KernelObjectTyped _logObject; -KernelObjectDirectory _untypedDirectory; -KernelObjectDirectory _processorDirectory; -KernelObjectPageMapping _pageMapping; -KernelObjectDirectory _initrd; -KernelObjectMessage _messageObject; - -#define POPULATE_ROOTDIR_MEMB(memb, i) \ -{ KernelObjectTyped *typed = JOVE_OBJECT_TYPED(memb); \ - __rootdir.children[i] = typed; \ - typed->parent = JOVE_OBJECT_TYPED(&__rootdir); \ - typed->membi = i; \ - if(_syscall_invoke_objdir_getmemb(&__rootdir, i, &typed->type) != 0) { \ - jove_kprintf("Failed to populate objdir root member %i\n", i); \ - spin_fail(); \ - } \ -} - -static void -s_populate_rootdir(init_data_t *init_data) -{ - __rootdir.typed.parent = NULL; - __rootdir.children[0] = JOVE_OBJECT_TYPED(&__rootdir); - - POPULATE_ROOTDIR_MEMB(&_logObject, init_data->log_object); - POPULATE_ROOTDIR_MEMB(&_untypedDirectory, init_data->untyped_data_dir); - POPULATE_ROOTDIR_MEMB(&_processorDirectory, init_data->processor_dir); - POPULATE_ROOTDIR_MEMB(&_pageMapping, init_data->pm_object); - POPULATE_ROOTDIR_MEMB(&_initrd, init_data->initrd_dir); - POPULATE_ROOTDIR_MEMB(&_messageObject, init_data->message_object); - - //Populate untyped table - for(int i = 1; i < 256; i++) { - KernelObjectUntyped untyped; - untyped.typed.parent = &_untypedDirectory; - untyped.typed.membi = i; - if(_syscall_invoke_objdir_getmemb(&_untypedDirectory, i, &untyped.typed.type) != 0) { - jove_kprintf("Failed to get member %i of untyped directory\n", i); - spin_fail(); - } - if(untyped.typed.type != KO_MEMORY_UNTYPED) continue; - _untypedDirectory.children[i] = init_bumpalloc(sizeof(KernelObjectUntyped)); - memcpy(_untypedDirectory.children[i], &untyped, sizeof(KernelObjectUntyped)); - - _syscall_invoke_untyped_size(&untyped, &untyped.bytes); - _syscall_invoke_untyped_alignment(&untyped, &untyped.alignment); - - jove_kprintf("Untyped %i size %X align %X\n", i, untyped.bytes, untyped.alignment); - } -} +KernelObjectDirectory untypedDirectory; void -main(init_data_t *init_data) +main(void *message_ptr) { libjove_init( - (uintmax_t)init_data->message_object, - (void*)init_data->message_object_address); - jove_kprintf("Hello, Userland!\n"); + INIT_OBJECT_MESSAGE, + message_ptr); + _jove_alloc = init_bumpalloc; - s_populate_rootdir(init_data); + jove_kprintf("Hello, Userland!\n"); + pager_setup(); for(;;); } - -__attribute__((section(".text.start"))) -__attribute__((naked)) -void -_start(void) -{ - __asm__ volatile("\ - popq %%rdi; \ - jmp main"::); -} diff --git a/apps/init/memory.h b/apps/init/memory.h index 61d16d6..378de60 100644 --- a/apps/init/memory.h +++ b/apps/init/memory.h @@ -1,6 +1,10 @@ #ifndef _INIT_MEMORY_H #define _INIT_MEMORY_H 1 +#include +extern KernelObjectDirectory untypedDirectory; + +void pager_setup(); #endif diff --git a/apps/init/x86_64.ld b/apps/init/x86_64.ld deleted file mode 100644 index 45b08f5..0000000 --- a/apps/init/x86_64.ld +++ /dev/null @@ -1,10 +0,0 @@ -OUTPUT_ARCH(i386:x86-64) - -PAGESIZE = CONSTANT(MAXPAGESIZE); - -SECTIONS -{ - . = 0x1000; - .text BLOCK(PAGESIZE) : ALIGN(PAGESIZE) { *(.text.start) *(.text) *(.rodata) } - .data BLOCK(PAGESIZE) : ALIGN(PAGESIZE) { *(.data) *(.bss) } -} -- cgit v1.2.1