summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2025-08-19 15:04:04 -0400
committerJon Santmyer <jon@jonsantmyer.com>2025-08-19 15:04:04 -0400
commit858a52c06a4615bd58a6a906333f2ad707d41c0a (patch)
tree16870cd4d67da283567a72a74d28c04464da292a
parent65ba015d6c1f248d36ad01a653bc49637804b15b (diff)
downloadjove-os-858a52c06a4615bd58a6a906333f2ad707d41c0a.tar.gz
jove-os-858a52c06a4615bd58a6a906333f2ad707d41c0a.tar.bz2
jove-os-858a52c06a4615bd58a6a906333f2ad707d41c0a.zip
usermode pager
-rw-r--r--Makefile2
-rw-r--r--apps/init/Makefile3
-rw-r--r--apps/init/arch/x86_64/link.ld (renamed from apps/init/x86_64.ld)0
-rw-r--r--apps/init/arch/x86_64/paging.c109
-rw-r--r--apps/init/arch/x86_64/start.c11
-rw-r--r--apps/init/main.c77
-rw-r--r--apps/init/memory.h4
-rwxr-xr-xinitrd/files/bin/initbin16656 -> 16600 bytes
m---------kernel0
-rw-r--r--lib/libc-headless/stdio/sprintf.c2
-rw-r--r--lib/libjove/Makefile5
-rw-r--r--lib/libjove/arch/x86_64/invoke-pagemap.c36
-rw-r--r--lib/libjove/arch/x86_64/object/directory.c15
-rw-r--r--lib/libjove/arch/x86_64/object/pagemap.c105
-rw-r--r--lib/libjove/error.c22
-rw-r--r--lib/libjove/include/arch/x86_64/object-pagemap.h44
-rw-r--r--lib/libjove/include/arch/x86_64/syscall.h12
-rw-r--r--lib/libjove/include/error.h22
-rw-r--r--lib/libjove/include/jove.h5
-rw-r--r--lib/libjove/include/object-dir.h82
-rw-r--r--lib/libjove/include/object-untyped.h91
-rw-r--r--lib/libjove/include/syscall.h11
-rw-r--r--lib/libjove/libjove.c7
-rw-r--r--lib/libjove/object/directory.c187
-rw-r--r--lib/libjove/object/untyped.c127
-rw-r--r--lib/libjove/syscall/invoke-objdir.c27
-rw-r--r--sysroot/boot/initrd.tarbin20480 -> 20480 bytes
27 files changed, 890 insertions, 116 deletions
diff --git a/Makefile b/Makefile
index b63fa27..c9eb674 100644
--- a/Makefile
+++ b/Makefile
@@ -58,7 +58,7 @@ test: $(TEST_HDD) $(KERNEL_BIN) $(INITRD_TAR) $(SYSROOTDIR)
sudo umount $(TEST_HDD_DIR)
sudo losetup -d $$LOOPBACK_DEV
sudo rm -rf $(TEST_HDD_DIR)
- qemu-system-x86_64 -m 512M -M q35 -bios ovmf-x64/OVMF.fd -net none -smp 4 -hda test.hdd -serial stdio -no-shutdown -no-reboot -s -d int -d guest_errors
+ qemu-system-x86_64 -m 512M -M q35 -bios ovmf-x64/OVMF.fd -net none -smp 4 -hda test.hdd -serial stdio -no-shutdown -no-reboot -s
.PHONY: $(TEST_HDD)
$(TEST_HDD):
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/x86_64.ld b/apps/init/arch/x86_64/link.ld
index 45b08f5..45b08f5 100644
--- a/apps/init/x86_64.ld
+++ b/apps/init/arch/x86_64/link.ld
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 <jove/arch/x86_64/object-pagemap.h>
+#include <stdbool.h>
+
+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 <jove/jove.h>
#include <jove/object.h>
#include <jove/syscall.h>
-#include <jove/arch/x86_64/object-pagemap.h>
+
+#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 <jove/object.h>
+extern KernelObjectDirectory untypedDirectory;
+
+void pager_setup();
#endif
diff --git a/initrd/files/bin/init b/initrd/files/bin/init
index 6fa149d..c86f9d1 100755
--- a/initrd/files/bin/init
+++ b/initrd/files/bin/init
Binary files differ
diff --git a/kernel b/kernel
-Subproject c4f8ef91f18d854a4ede7a94e95b2eab898d696
+Subproject 772717dc22e04b4d168d0f77bee6b6357118768
diff --git a/lib/libc-headless/stdio/sprintf.c b/lib/libc-headless/stdio/sprintf.c
index 2881bd5..dd78572 100644
--- a/lib/libc-headless/stdio/sprintf.c
+++ b/lib/libc-headless/stdio/sprintf.c
@@ -108,7 +108,7 @@ conversion_int:
for(uintmax_t v = value, i = numc - 1; v != 0; v /= radix, i--) {
if(written + i >= size) continue;
int digit = v % radix;
- char c = digit > 10 ? (digit + 'a' - 10) : (digit + '0');
+ char c = digit >= 10 ? (digit + 'a' - 10) : (digit + '0');
if(is_caps) c = toupper(c);
str[written + i] = c;
}
diff --git a/lib/libjove/Makefile b/lib/libjove/Makefile
index cc5f347..024d4fe 100644
--- a/lib/libjove/Makefile
+++ b/lib/libjove/Makefile
@@ -1,8 +1,11 @@
include $(CONFIG)
-CDIRS := syscall object arch/$(TARGET_MACHINE)
+CDIRS := syscall object
+
CFILES := $(wildcard *.c)
CFILES += $(foreach dir,$(CDIRS),$(wildcard $(dir)/*.c))
+CFILES += $(wildcard arch/$(TARGET_MACHINE)/*.c)
+CFILES += $(foreach dir,$(CDIRS),$(wildcard arch/$(TARGET_MACHINE)/$(dir)/*.c))
OFILES := $(patsubst %.c,%.o,$(CFILES))
diff --git a/lib/libjove/arch/x86_64/invoke-pagemap.c b/lib/libjove/arch/x86_64/invoke-pagemap.c
index 8357904..e3f3dff 100644
--- a/lib/libjove/arch/x86_64/invoke-pagemap.c
+++ b/lib/libjove/arch/x86_64/invoke-pagemap.c
@@ -1,3 +1,4 @@
+#include "arch/x86_64/syscall.h"
#include <arch/x86_64/object-pagemap.h>
#include <kernel/syscall.h>
#include <kernel/arch/x86_64/syscall.h>
@@ -7,14 +8,41 @@
#include <jove/jove.h>
int
-_syscall_invoke_mapping_get(KernelObjectPageMapping *mapping, uint16_t pmli, KernelObjectPageMapping *dest)
+_syscall_invoke_mapping_exists(KernelObjectPageMap *map, uint8_t depth, uint16_t *path)
{
uint8_t *syscallData = _syscall_message_ptr;
int syscall_at = 0;
- SYSCALL_PAYLOAD_PUTOBJ(syscallData, syscall_at, mapping);
- SYSCALL_PAYLOAD_PUTL(syscallData, syscall_at, INVOKE_MAPPING_GET, uint8_t);
- SYSCALL_PAYLOAD_PUTL(syscallData, syscall_at, pmli, uint16_t);
+ SYSCALL_PAYLOAD_PUTOBJ(syscallData, syscall_at, map);
+ SYSCALL_PAYLOAD_PUTL(syscallData, syscall_at, INVOKE_MAPPING_EXISTS, uint8_t);
+ SYSCALL_PAYLOAD_PUTPML(syscallData, syscall_at, depth, path);
+
+ return _syscall_invoke();
+}
+
+int
+_syscall_invoke_mapping_map(KernelObjectPageMap *map, uint8_t depth, uint16_t *path, KernelObjectUntyped *untyped)
+{
+ uint8_t *syscallData = _syscall_message_ptr;
+ int syscall_at = 0;
+
+ SYSCALL_PAYLOAD_PUTOBJ(syscallData, syscall_at, map);
+ SYSCALL_PAYLOAD_PUTL(syscallData, syscall_at, INVOKE_MAPPING_MAP, uint8_t);
+ SYSCALL_PAYLOAD_PUTPML(syscallData, syscall_at, depth, path);
+ SYSCALL_PAYLOAD_PUTOBJ(syscallData, syscall_at, untyped);
+
+ return _syscall_invoke();
+}
+
+int
+_syscall_invoke_mapping_unmap(KernelObjectPageMap *map, uint8_t depth, uint16_t *path, KernelObjectUntyped *dest)
+{
+ uint8_t *syscallData = _syscall_message_ptr;
+ int syscall_at = 0;
+
+ SYSCALL_PAYLOAD_PUTOBJ(syscallData, syscall_at, map);
+ SYSCALL_PAYLOAD_PUTL(syscallData, syscall_at, INVOKE_MAPPING_UNMAP, uint8_t);
+ SYSCALL_PAYLOAD_PUTPML(syscallData, syscall_at, depth, path);
SYSCALL_PAYLOAD_PUTOBJ(syscallData, syscall_at, dest);
return _syscall_invoke();
diff --git a/lib/libjove/arch/x86_64/object/directory.c b/lib/libjove/arch/x86_64/object/directory.c
new file mode 100644
index 0000000..01f57c4
--- /dev/null
+++ b/lib/libjove/arch/x86_64/object/directory.c
@@ -0,0 +1,15 @@
+#include <object.h>
+#include <arch/x86_64/object-pagemap.h>
+
+JoveError
+_jove_objdir_sync_at_arch(KernelObjectDirectory *dir, uint8_t i, obj_type_t type, KernelObjectTyped **memb)
+{
+ KernelObjectTyped *dirmemb = NULL;
+ switch(type) {
+ case KO_MEMORY_MAPPING:
+ dirmemb = JOVE_OBJECT_TYPED(_jove_alloc_pagemap(dir, i));
+ if(memb) *memb = dirmemb;
+ break;
+ }
+ return EJOVE_OK;
+}
diff --git a/lib/libjove/arch/x86_64/object/pagemap.c b/lib/libjove/arch/x86_64/object/pagemap.c
new file mode 100644
index 0000000..c58d7c6
--- /dev/null
+++ b/lib/libjove/arch/x86_64/object/pagemap.c
@@ -0,0 +1,105 @@
+#include <object.h>
+#include <jove.h>
+#include <error.h>
+#include <kernel/error.h>
+#include <string.h>
+#include <arch/x86_64/object-pagemap.h>
+#include <arch/x86_64/syscall.h>
+
+KernelObjectPageMap*
+jove_object_as_pagemap(KernelObjectTyped *typed)
+{
+ if(typed->type == KO_MEMORY_MAPPING) return (KernelObjectPageMap*)typed;
+ jove_errno = EJOVE_BADOBJ;
+ return NULL;
+}
+
+void
+_jove_alloc_pagemap_inplace(
+ KernelObjectPageMap *pagemap,
+ KernelObjectDirectory *dir,
+ uint8_t memb)
+{
+ *pagemap = (KernelObjectPageMap) {
+ .typed = (KernelObjectTyped) {
+ .parent = dir,
+ .type = KO_MEMORY_MAPPING,
+ .membi = memb
+ },
+ };
+ dir->children[memb] = JOVE_OBJECT_TYPED(pagemap);
+}
+
+KernelObjectPageMap*
+_jove_alloc_pagemap(
+ KernelObjectDirectory *dir,
+ uint8_t memb)
+{
+ if(_jove_alloc == NULL) {
+ jove_errno = EJOVE_NOALLOC;
+ return NULL;
+ }
+ if(dir->children[memb] != NULL) {
+ jove_errno = EJOVE_FULL;
+ return NULL;
+ }
+
+ KernelObjectPageMap *pagemap = _jove_alloc(sizeof(KernelObjectPageMap));
+ if(pagemap == NULL) return NULL;
+
+ _jove_alloc_pagemap_inplace(pagemap, dir, memb);
+ jove_errno = EJOVE_OK;
+ return pagemap;
+}
+
+int
+jove_pagemap_exists(
+ KernelObjectPageMap *map,
+ uint8_t depth,
+ uint16_t *path
+ )
+{
+ if(!_jove_alloc) {
+ jove_errno = EJOVE_NOALLOC;
+ return 0;
+ }
+ int kerr = _syscall_invoke_mapping_exists(map, depth, path);
+ if(kerr == KE_DNE) return 0;
+
+ int jerr = jove_error_from_kerror(kerr);
+
+ if(jerr) {
+ jove_errno = jerr;
+ return 0;
+ }
+ return 1;
+}
+
+JoveError
+jove_pagemap_map(
+ KernelObjectPageMap *map,
+ uint8_t depth,
+ uint16_t *path,
+ KernelObjectUntyped *untyped)
+{
+ if(jove_untyped_size(untyped) != 0x1000) {
+ return EJOVE_BADSIZE;
+ }
+
+ return jove_error_from_kerror(_syscall_invoke_mapping_map(map, depth, path, untyped));
+}
+
+JoveError
+jove_pagemap_unmap(
+ KernelObjectPageMap *map,
+ uint8_t depth,
+ uint16_t *path,
+ KernelObjectUntyped *untyped)
+{
+ JoveError err = jove_error_from_kerror(_syscall_invoke_mapping_unmap(map, depth, path, untyped));
+ if(err) return err;
+
+ untyped->alignment = 0x1000;
+ untyped->bytes = 0x1000;
+ return EJOVE_OK;
+}
diff --git a/lib/libjove/error.c b/lib/libjove/error.c
new file mode 100644
index 0000000..4c0d043
--- /dev/null
+++ b/lib/libjove/error.c
@@ -0,0 +1,22 @@
+#include <error.h>
+#include <kernel/error.h>
+
+JoveError
+jove_error_from_kerror(int kerror)
+{
+ switch(kerror) {
+ case KE_OK:
+ return EJOVE_OK;
+ case KE_BADMSG:
+ case KE_BADOBJ:
+ return EJOVE_BADOBJ;
+ case KE_BADCALL:
+ case KE_BADFUNC:
+ return EJOVE_NOIMPL;
+ case KE_BADSIZE:
+ return EJOVE_BADSIZE;
+ case KE_DNE:
+ return EJOVE_DNE;
+ default: return EJOVE_KERROR;
+ }
+}
diff --git a/lib/libjove/include/arch/x86_64/object-pagemap.h b/lib/libjove/include/arch/x86_64/object-pagemap.h
index 55b0570..48e959e 100644
--- a/lib/libjove/include/arch/x86_64/object-pagemap.h
+++ b/lib/libjove/include/arch/x86_64/object-pagemap.h
@@ -2,13 +2,51 @@
#define _LIBJOVE_ARCH_x86_64_OBJECT_PAGEMAP_H 1
#include <jove/object-typed.h>
+#include <jove/object-dir.h>
+#include <jove/object-untyped.h>
-typedef struct KernelObjectPageMapping
+typedef struct KernelObjectPageMap
{
KernelObjectTyped typed;
- uint8_t level;
-} KernelObjectPageMapping;
+} KernelObjectPageMap;
+KernelObjectPageMap *jove_object_as_pagemap(KernelObjectTyped *typed);
+/**@FUNC Populates a given region of memory for a page map value.
+ * @PARAM pagemap address of pagemap cache object.
+ * @PARAM dir directory this memory is a member of.
+ * @PARAM memb index into directory to place object.*/
+void _jove_alloc_pagemap_inplace(
+ KernelObjectPageMap *pagemap,
+ KernelObjectDirectory *dir,
+ uint8_t memb);
+
+/**@FUNC Allocates a region of memory to represent a page map.
+ * @PARAM dir directory to place new value in.
+ * @PARAM memb index into directory to place object.
+ * @RETURN newly allocated object. NULL on failure.
+ * Possible failures:
+ * EJOVE_FULL: Slot is already taken by an existing object.
+ * EJOVE_NOALLOC: libjove does not have an allocator yet.*/
+KernelObjectPageMap* _jove_alloc_pagemap(
+ KernelObjectDirectory *dir,
+ uint8_t memb);
+
+int jove_pagemap_exists(
+ KernelObjectPageMap *map,
+ uint8_t depth,
+ uint16_t *path);
+
+JoveError jove_pagemap_map(
+ KernelObjectPageMap *map,
+ uint8_t depth,
+ uint16_t *path,
+ KernelObjectUntyped *page);
+
+JoveError jove_pagemap_map_unmap(
+ KernelObjectPageMap *map,
+ uint8_t depth,
+ uint16_t *path,
+ KernelObjectUntyped *dest);
#endif
diff --git a/lib/libjove/include/arch/x86_64/syscall.h b/lib/libjove/include/arch/x86_64/syscall.h
index 1d7df53..74fb389 100644
--- a/lib/libjove/include/arch/x86_64/syscall.h
+++ b/lib/libjove/include/arch/x86_64/syscall.h
@@ -4,9 +4,17 @@
#include <stdint.h>
#include <kernel/object.h>
-#include <jove/object-path.h>
+#include <jove/arch/x86_64/object-pagemap.h>
+#include <jove/syscall.h>
-int _syscall_invoke_mapping_get(KernelObjectPath path, uint16_t pmli, KernelObjectPath destPath);
+#define SYSCALL_PAYLOAD_PUTPML(payload, payload_at, depth, path) \
+ if(payload_at + 1 + ((depth + 1) * sizeof(uint16_t)) > KO_MESSAGE_BYTES) return -1; \
+ *((uint8_t*)&payload[payload_at++]) = depth; \
+ for(uint8_t i = 0; i < depth + 1; i++) *((uint16_t*)&payload[payload_at + (i * 2)]) = path[i]; \
+ payload_at += (depth + 1) * 2
+int _syscall_invoke_mapping_exists(KernelObjectPageMap *map, uint8_t depth, uint16_t *path);
+int _syscall_invoke_mapping_map(KernelObjectPageMap *map, uint8_t depth, uint16_t *path, KernelObjectUntyped *untyped);
+int _syscall_invoke_mapping_unmap(KernelObjectPageMap *map, uint8_t depth, uint16_t *path, KernelObjectUntyped *dest);
#endif
diff --git a/lib/libjove/include/error.h b/lib/libjove/include/error.h
new file mode 100644
index 0000000..bbf7a51
--- /dev/null
+++ b/lib/libjove/include/error.h
@@ -0,0 +1,22 @@
+#ifndef _LIBJOVE_ERROR_H
+#define _LIBJOVE_ERROR_H 1
+
+typedef enum _JoveError{
+ EJOVE_OK = 0,
+ EJOVE_KERROR,
+ EJOVE_NOALLOC,
+ EJOVE_NOFREE,
+ EJOVE_NOIMPL,
+ EJOVE_FULL,
+ EJOVE_BADOBJ,
+ EJOVE_BADSIZE,
+ EJOVE_BADARG,
+ EJOVE_DNE,
+ EJOVE_TOOBIG
+} JoveError;
+
+extern JoveError jove_errno;
+
+JoveError jove_error_from_kerror(int kerror);
+
+#endif
diff --git a/lib/libjove/include/jove.h b/lib/libjove/include/jove.h
index 2efef3e..87eecb3 100644
--- a/lib/libjove/include/jove.h
+++ b/lib/libjove/include/jove.h
@@ -2,10 +2,15 @@
#define _LIBJOVE_JOVE_H 1
#include <stdint.h>
+#include <stddef.h>
extern uintmax_t _syscall_message_box;
extern void *_syscall_message_ptr;
+extern void *(*_jove_alloc)(size_t);
+extern void (*_jove_free)(void*);
+extern void *(*_jove_realloc)(void*, size_t);
+
void libjove_init(uintmax_t box, void *boxptr);
void jove_kprintf(const char *restrict fmt, ...);
diff --git a/lib/libjove/include/object-dir.h b/lib/libjove/include/object-dir.h
index f258089..e4d9aaf 100644
--- a/lib/libjove/include/object-dir.h
+++ b/lib/libjove/include/object-dir.h
@@ -6,12 +6,92 @@
#include <kernel/object.h>
#include <jove/object-typed.h>
+#include <jove/error.h>
-/**@STRUCT Represents a kobjdir.*/
+/**@STRUCT Represents cached information about a KO_OBJDIR.
+ * To update the information this struct contains, call jove_objdir_sync.*/
typedef struct _KernelObjectDirectory {
KernelObjectTyped typed;
+
+ uint8_t lastmemb;
+ uint8_t firstfree;
+
KernelObjectTyped *children[256];
} KernelObjectDirectory;
extern KernelObjectDirectory __rootdir;
+KernelObjectDirectory *jove_object_as_objdir(KernelObjectTyped *typed);
+
+/**@FUNC Populates a objdir struct for an empty directory at dir:memb.
+ * @PARAM dir address to populate.
+ * @PARAM parent directory to make dir child of.
+ * @PARAM memb index to place new objdir.*/
+void _jove_alloc_objdir_inplace(
+ KernelObjectDirectory *dir,
+ KernelObjectDirectory *parent,
+ uint8_t memb);
+
+/**@FUNC Allocates a block of memory to represent a kernel objdir.
+ * @PARAM parent directory to place new member into.
+ * @PARAM memb index to place new objdir.
+ * @RETURN pointer to new objdir.
+ * Possible failures:
+ * EJOVE_NOALLOC: libjove is missing an allocator.
+ * EJOVE_FULL: space at memb is already taken.*/
+KernelObjectDirectory *_jove_alloc_objdir(
+ KernelObjectDirectory *parent,
+ uint8_t memb);
+
+/**@FUNC Updates the dir struct with information obtained through the kernel.
+ * @PARAM dir directory to sync.
+ * @RETURN error code. 0 on success*/
+JoveError jove_objdir_sync(KernelObjectDirectory *dir);
+
+/**@FUNC Updates the dir struct at the given index with information obtained
+ * through the kernel.
+ * @PARAM dir directory to sync.
+ * @PARAM i index to sync.
+ * @PARAM memb pointer to place typed object in. Nullable
+ * @RETURN error code. 0 on success.*/
+JoveError jove_objdir_sync_at(KernelObjectDirectory *dir, uint8_t i, KernelObjectTyped** memb);
+
+/**@FUNC Returns the number of populated entries this directory holds.
+ * @PARAM dir directory to check
+ * @RETURN number of entries. negative return values indicate an error.*/
+int jove_objdir_nmemb(KernelObjectDirectory *dir);
+
+/**@FUNC Gets the highest populated index in a given directory.
+ * @PARAM dir directory to check.
+ * @RETURN last populated entry. negative return values indicate an error.*/
+int jove_objdir_lastmemb(KernelObjectDirectory *dir);
+
+/**@FUNC Gets the kernel object at a given index.
+ * This function only checks the cached result. If the directory has changed
+ * without updating the cache, jove_objdir_sync MUST be called first.
+ *
+ * @PARAM dir directory to check in.
+ * @PARAM index index to check.
+ * @RETURN the object at the given index. NULL if the spot is empty.*/
+KernelObjectTyped *jove_objdir_get(KernelObjectDirectory *dir, uint8_t index);
+
+/**@FUNC Moves a kernel object in this directory to a different place/directory.
+ * @PARAM dir directory holding the object.
+ * @PARAM memb member index of the object.
+ * @PARAM dest_dir destination directory.
+ * @PARAM dest_memb destination member.*/
+JoveError jove_objdir_move(
+ KernelObjectDirectory *dir,
+ uint8_t memb,
+ KernelObjectDirectory *dest_dir,
+ uint8_t dest_memb);
+
+JoveError jove_object_move(
+ KernelObjectTyped *typed,
+ KernelObjectDirectory *dest_dir,
+ uint8_t dest_memb);
+
+JoveError jove_object_move_inplace(
+ KernelObjectTyped *typed,
+ KernelObjectTyped *dest);
+
#endif
diff --git a/lib/libjove/include/object-untyped.h b/lib/libjove/include/object-untyped.h
index ea1185d..e7715b0 100644
--- a/lib/libjove/include/object-untyped.h
+++ b/lib/libjove/include/object-untyped.h
@@ -2,38 +2,73 @@
#define _LIBJOVE_OBJECT_UNTYPED_H 1
#include <jove/object-typed.h>
+#include <jove/object-dir.h>
/**@STRUCT Represents a KO_MEMOY_UNTYPED*/
-typedef struct KernelObjectUntyped
+typedef struct _KernelObjectUntyped
{
KernelObjectTyped typed;
- size_t bytes, alignment;
+ size_t bytes;
+ intmax_t alignment;
+
+ KernelObjectTyped *children_head;
+ KernelObjectTyped *sibling;
} KernelObjectUntyped;
-/**@FUNC Gets the size of the given untyped memory block.
- * @PARAM untyped block of memory to get size of.
- * @PARAM bytes address to put size variable into.
- * @RETURN error code. 0 on success.*/
-int jove_untyped_size(KernelObjectUntyped *untyped, size_t *bytes);
-
-/**@FUNC Splits an untyped block of memory into a given size and the remainder.
- * @PARAM untyped block of memory to split.
- * @PARAM bytes number of bytes to split for.
- * @PARAM dest destination slot to place the new block.
- * @RETURN error code. 0 on success.*/
-int jove_untyped_split(KernelObjectUntyped *untyped, size_t bytes, KernelObjectUntyped *dest);
-
-/**@FUNC Merges two untyped memory blocks into a single memory block.
- * The two blocks are expected to be adjacent.
- * If successful, b is merged _into_ a and becomes empty.
- * @PARAM a first block.
- * @PARAM b second block.
- * @RETURN error code. 0 on success.*/
-int jove_untyped_merge(KernelObjectUntyped *a, KernelObjectUntyped *b);
-
-/**@FUNC Gets the page alignment of the given untyped memory block.
- * @PARAM untyped block of memory to get alignment of.
- * @PARAM align pointer to returned value.
- * @RETURN error code. 0 on success.*/
-int jove_untyped_alignment(KernelObjectUntyped *untyped, size_t *align);
+/**@FUNC INTERNAL FUNCTION DO NOT USE.
+ * Initializes a block of memory as an untyped object.
+ * @PARAM untyped pointer to new block of memory.
+ * @PARAM parent directory this new object is a member of.
+ * @PARAM membi index to place this new object.*/
+void _jove_alloc_untyped_inplace(KernelObjectUntyped *untyped, struct _KernelObjectDirectory *parent, uint8_t membi);
+
+/**@FUNC INTERNAL FUNCTION DO NOT USE.
+ * Allocates a block of memory representing an untyped object into the heap.
+ * @PARAM parent directory this new object is a member of.
+ * @PARAM membi index to place this new object.
+ * @RETURN pointer to allocated object. NULL on failure.
+ * Possible failures:
+ * EJOVE_NOALLOC: libjove does not have an allocator set yet.
+ * EJOVE_FULL: destination is already taken.*/
+KernelObjectUntyped *_jove_alloc_untyped(struct _KernelObjectDirectory *parent, uint8_t membi);
+
+/**@FUNC Changes pointer type of typed object to untyped if correct.
+ * @PARAM typed pointer to convert.
+ * @RETURN pointer as KernelObjectUntyped*, NULL on failure.
+ * Possible failures:
+ * EJOVE_BADOBJ: passed object is not an untyped.*/
+KernelObjectUntyped *jove_object_as_untyped(KernelObjectTyped *typed);
+
+/**@FUNC Gets the number of bytes a given untyped block represents.
+ * @PARAM untyped block of untyped memory.
+ * @RETURN number of bytes. negative on failure.
+ * Possible failures:
+ * EJOVE_BADOBJ: passed object does not exist / is not an untyped. */
+int jove_untyped_size(KernelObjectUntyped *untyped);
+
+/**@FUNC Gets the byte alignment of a given untyped block up to a page.
+ * @PARAM untyped block of untyped memory.
+ * @RETURN alignment in bytes. negative on failure.*/
+int jove_untyped_alignment(KernelObjectUntyped *untyped);
+
+/**@FUNC Splits a given untyped block of memory into a block with the given size
+ * and the remainder. New untyped object is stored in dest at destmemb.
+ * @PARAM untyped block of untyped memory to split.
+ * @PARAM bytes number of bytes the new block should have.
+ * Minimum sizeof(size_t)
+ * @PARAM dest directory to store the new block.
+ * @PARAM destmemb index in dest to store new block.
+ * @RETURN Newly created block of memory. NULL on failure.
+ * Possible failures:
+ * EJOVE_BADSIZE: bytes < sizeof(size_t)
+ * EJOVE_BADOBJ: dest or untyped are incorrect types / do not exist.*/
+KernelObjectUntyped *jove_untyped_split(
+ KernelObjectUntyped *untyped, size_t bytes,
+ KernelObjectDirectory *dest, uint8_t destmemb);
+
+JoveError jove_untyped_split_inplace(
+ KernelObjectUntyped *untyped,
+ size_t bytes,
+ KernelObjectUntyped *dest);
+
#endif
diff --git a/lib/libjove/include/syscall.h b/lib/libjove/include/syscall.h
index 432be85..5d872a3 100644
--- a/lib/libjove/include/syscall.h
+++ b/lib/libjove/include/syscall.h
@@ -7,25 +7,28 @@
#include <jove/object.h>
#define SYSCALL_PAYLOAD_PUTL(buf, at, v, type) \
- if(at + sizeof(type) > KO_MESSAGE_BYTES) return -1; \
+ if(at + sizeof(type) > KO_MESSAGE_BYTES) return EJOVE_TOOBIG; \
*((type*)(&buf[at])) = v; \
at += sizeof(type)
#define SYSCALL_PAYLOAD_SAVEPTR(buf, at, type, val) \
- if(at + sizeof(type) >= KO_MESSAGE_BYTES) return -1; \
+ if(at + sizeof(type) >= KO_MESSAGE_BYTES) return EJOVE_TOOBIG; \
val = (type*)(&buf[at]); \
at += sizeof(type)
#define SYSCALL_PAYLOAD_PUTOBJ(buf, at, obj) \
at = path_tobuf(JOVE_OBJECT_TYPED(obj), buf, at, KO_MESSAGE_BYTES); \
- if(at < 0) return at
+ if(at < 0) return -at
int _syscall_invoke(void);
void _syscall_debug_putc(char c);
-int _syscall_invoke_objdir_nmemb(KernelObjectDirectory *dir, uint8_t *result);
int _syscall_invoke_objdir_getmemb(KernelObjectDirectory *dir, uint8_t member, obj_type_t *result);
+int _syscall_invoke_objdir_lastmemb(KernelObjectDirectory *dir, uint8_t *result);
+int _syscall_invoke_objdir_move(
+ KernelObjectDirectory *dir, uint8_t memb,
+ KernelObjectDirectory *dest_dir, uint8_t dest_memb);
int _syscall_invoke_untyped_size(KernelObjectUntyped *untyped, size_t *bytes);
int _syscall_invoke_untyped_split(KernelObjectUntyped *path, size_t bytes, KernelObjectUntyped *dest);
diff --git a/lib/libjove/libjove.c b/lib/libjove/libjove.c
index fe1c080..5ad45ac 100644
--- a/lib/libjove/libjove.c
+++ b/lib/libjove/libjove.c
@@ -1,8 +1,15 @@
#include "include/jove.h"
+#include "error.h"
uintmax_t _syscall_message_box = 0;
void *_syscall_message_ptr = 0;
+JoveError jove_errno;
+
+void *(*_jove_alloc)(size_t) = NULL;
+void (*_jove_free)(void*) = NULL;
+void *(*_jove_realloc)(void*, size_t) = NULL;
+
void
libjove_init(uint64_t box, void *boxptr)
{
diff --git a/lib/libjove/object/directory.c b/lib/libjove/object/directory.c
index a9487e8..9c12d5b 100644
--- a/lib/libjove/object/directory.c
+++ b/lib/libjove/object/directory.c
@@ -1,4 +1,191 @@
+#include "object-dir.h"
#include <object.h>
+#include <jove.h>
#include <syscall.h>
KernelObjectDirectory __rootdir;
+
+KernelObjectDirectory*
+jove_object_as_objdir(KernelObjectTyped *typed)
+{
+ if(typed->type == KO_OBJECT_DIRECTORY) return (KernelObjectDirectory*)typed;
+ return NULL;
+}
+
+void
+_jove_alloc_objdir_inplace(
+ KernelObjectDirectory *dir,
+ KernelObjectDirectory *parent,
+ uint8_t memb)
+{
+ *dir = (KernelObjectDirectory) {
+ .typed = (KernelObjectTyped) {
+ .parent = parent,
+ .membi = memb,
+ .type = KO_OBJECT_DIRECTORY
+ },
+ .lastmemb = 0,
+ .firstfree = 0,
+ .children = { 0 }
+ };
+
+ parent->children[memb] = JOVE_OBJECT_TYPED(dir);
+}
+
+KernelObjectDirectory*
+_jove_alloc_objdir(
+ KernelObjectDirectory *parent,
+ uint8_t memb)
+{
+ if(!_jove_alloc) {
+ jove_errno = EJOVE_NOALLOC;
+ return NULL;
+ }
+ if(parent->children[memb]) {
+ jove_errno = EJOVE_FULL;
+ return NULL;
+ }
+
+ KernelObjectDirectory *dir = _jove_alloc(sizeof(KernelObjectDirectory));
+ if(dir == NULL) return NULL;
+
+ _jove_alloc_objdir_inplace(dir, parent, memb);
+ jove_errno = 0;
+ return dir;
+}
+
+JoveError
+jove_objdir_sync(KernelObjectDirectory *dir)
+{
+ if(dir->lastmemb) return dir->lastmemb;
+
+ int kerr = _syscall_invoke_objdir_lastmemb(dir, &dir->lastmemb);
+ jove_errno = jove_error_from_kerror(kerr);
+
+ return dir->lastmemb;
+}
+
+extern JoveError
+_jove_objdir_sync_at_arch(
+ KernelObjectDirectory *dir,
+ uint8_t i,
+ obj_type_t type,
+ KernelObjectTyped **memb
+ );
+
+JoveError
+jove_objdir_sync_at(KernelObjectDirectory *dir, uint8_t i, KernelObjectTyped** memb)
+{
+ obj_type_t type;
+ int err = _syscall_invoke_objdir_getmemb(dir, i, &type);
+ if(err != 0) return err;
+
+ KernelObjectTyped *dirmemb = dir->children[i];
+ if(dirmemb != NULL) {
+ if(dirmemb->type == type) {
+ if(memb) *memb = dirmemb;
+ return EJOVE_OK;
+ }
+ if(_jove_free == NULL) {
+ return EJOVE_NOFREE;
+ }
+ _jove_free(dirmemb);
+ }
+ if(_jove_alloc == NULL)
+ return EJOVE_NOALLOC;
+
+ switch(type) {
+ case KO_NONE:
+ return EJOVE_OK;
+ case KO_OBJECT_DIRECTORY:
+ dirmemb = JOVE_OBJECT_TYPED(_jove_alloc_objdir(dir, i));
+ if(memb) *memb = dirmemb;
+ break;
+ case KO_MEMORY_UNTYPED:
+ {
+ dirmemb = JOVE_OBJECT_TYPED(_jove_alloc_untyped(dir, i));
+ if(memb) *memb = dirmemb;
+ break;
+ }
+ default:
+ return _jove_objdir_sync_at_arch(dir, i, type, memb);
+ }
+ return EJOVE_OK;
+}
+
+int
+jove_objdir_nmemb(KernelObjectDirectory *dir)
+{
+ int nmemb = 0;
+ for(unsigned i = 1; i < 256; i++) {
+ if(dir->children[i] != NULL) nmemb++;
+ }
+ return nmemb;
+}
+
+int
+jove_objdir_lastmemb(KernelObjectDirectory *dir)
+{
+ if(dir->lastmemb) return dir->lastmemb;
+ JoveError err = jove_error_from_kerror(_syscall_invoke_objdir_lastmemb(dir, &dir->lastmemb));
+ if(err) {
+ jove_errno = err;
+ return 0;
+ }
+ return dir->lastmemb;
+}
+
+KernelObjectTyped*
+jove_objdir_get(KernelObjectDirectory *dir, uint8_t i)
+{
+ return dir->children[i];
+}
+
+JoveError
+jove_objdir_move(
+ KernelObjectDirectory *dir,
+ uint8_t memb,
+ KernelObjectDirectory *dest_dir,
+ uint8_t dest_memb)
+{
+ if(!memb)
+ return EJOVE_BADOBJ;
+ if(!dir->children[memb])
+ return EJOVE_BADOBJ;
+
+ if(dest_memb)
+ return EJOVE_BADOBJ;
+ if(dest_dir->children[dest_memb])
+ return EJOVE_FULL;
+
+ int kerr = _syscall_invoke_objdir_move(dir, memb, dest_dir, dest_memb);
+ if(kerr) return jove_error_from_kerror(kerr);
+
+ KernelObjectTyped *move = dir->children[memb];
+ dir->children[memb] = NULL;
+ dest_dir->children[dest_memb] = move;
+
+ if(dir->lastmemb == move->membi) {
+ dir->lastmemb = 0;
+ }
+
+ move->parent = dest_dir;
+ move->membi = dest_memb;
+ return EJOVE_OK;
+}
+
+JoveError jove_object_move(
+ KernelObjectTyped *typed,
+ KernelObjectDirectory *dest_dir,
+ uint8_t dest_memb)
+{
+ return jove_objdir_move(typed->parent, typed->membi, dest_dir, dest_memb);
+}
+
+JoveError jove_object_move_inplace(
+ KernelObjectTyped *typed,
+ KernelObjectTyped *dest)
+{
+ return jove_objdir_move(typed->parent, typed->membi, dest->parent, dest->membi);
+}
+
diff --git a/lib/libjove/object/untyped.c b/lib/libjove/object/untyped.c
new file mode 100644
index 0000000..281bb60
--- /dev/null
+++ b/lib/libjove/object/untyped.c
@@ -0,0 +1,127 @@
+#include <jove.h>
+#include <object.h>
+#include <syscall.h>
+#include <error.h>
+#include <string.h>
+
+void
+_jove_alloc_untyped_inplace(
+ KernelObjectUntyped *untyped,
+ KernelObjectDirectory *parent,
+ uint8_t membi
+ )
+{
+ *untyped = (KernelObjectUntyped) {
+ .typed = (KernelObjectTyped) {
+ .type = KO_MEMORY_UNTYPED,
+ .parent = parent,
+ .membi = membi
+ },
+ .bytes = 0,
+ .alignment = -1,
+ .children_head = NULL,
+ .sibling = NULL
+ };
+
+ parent->children[membi] = (KernelObjectTyped*)untyped;
+ parent->lastmemb = 0;
+}
+
+KernelObjectUntyped*
+_jove_alloc_untyped(KernelObjectDirectory *parent, uint8_t membi)
+{
+ if(_jove_alloc == NULL) {
+ jove_errno = EJOVE_NOALLOC;
+ return NULL;
+ }
+ if(parent->children[membi] != NULL) {
+ jove_errno = EJOVE_FULL;
+ }
+
+ KernelObjectUntyped *untyped = _jove_alloc(sizeof(KernelObjectUntyped));
+
+ _jove_alloc_untyped_inplace(untyped, parent, membi);
+ return untyped;
+}
+
+KernelObjectUntyped*
+jove_object_as_untyped(KernelObjectTyped *typed)
+{
+ if(typed->type == KO_MEMORY_UNTYPED) return (KernelObjectUntyped*)typed;
+ jove_errno = EJOVE_BADOBJ;
+ return NULL;
+}
+
+int
+jove_untyped_size(KernelObjectUntyped *untyped)
+{
+ if(untyped->bytes != 0)
+ return untyped->bytes;
+
+ int e = _syscall_invoke_untyped_size(untyped, &untyped->bytes);
+ if(e) return jove_error_from_kerror(e);
+
+ return untyped->bytes;
+}
+
+int
+jove_untyped_alignment(KernelObjectUntyped *untyped)
+{
+ if(untyped->alignment >= 0)
+ return untyped->alignment;
+
+ int e = _syscall_invoke_untyped_alignment(untyped, (size_t*)&untyped->alignment);
+ if(e) return jove_error_from_kerror(e);
+
+ return untyped->alignment;
+}
+
+KernelObjectUntyped*
+jove_untyped_split(
+ KernelObjectUntyped *untyped,
+ size_t bytes,
+ KernelObjectDirectory *dest,
+ uint8_t destmemb
+ )
+{
+ if(!_jove_alloc) {
+ jove_errno = EJOVE_NOALLOC;
+ return NULL;
+ }
+
+ KernelObjectUntyped temp;
+ _jove_alloc_untyped_inplace(&temp, dest, destmemb);
+
+ jove_errno = jove_untyped_split_inplace(untyped, bytes, &temp);
+ if(jove_errno) return NULL;
+
+ KernelObjectUntyped *newuntyped = _jove_alloc(sizeof(KernelObjectUntyped));
+ memcpy(newuntyped, &temp, sizeof(KernelObjectUntyped));
+
+ dest->children[destmemb] = JOVE_OBJECT_TYPED(newuntyped);
+ return newuntyped;
+}
+
+JoveError jove_untyped_split_inplace(
+ KernelObjectUntyped *untyped,
+ size_t bytes,
+ KernelObjectUntyped *dest)
+{
+ if(jove_untyped_size(untyped) - sizeof(size_t) <= bytes) {
+ return EJOVE_BADSIZE;
+ }
+ if(bytes < sizeof(size_t)) {
+ return EJOVE_BADSIZE;;
+ }
+
+ int e = _syscall_invoke_untyped_split(untyped, bytes, dest);
+ if(e) {
+ return jove_error_from_kerror(e);
+ }
+
+ dest->bytes = bytes;
+ dest->alignment = -1;
+ untyped->bytes -= bytes;
+
+ return EJOVE_OK;
+}
diff --git a/lib/libjove/syscall/invoke-objdir.c b/lib/libjove/syscall/invoke-objdir.c
index 462c282..6ee39e4 100644
--- a/lib/libjove/syscall/invoke-objdir.c
+++ b/lib/libjove/syscall/invoke-objdir.c
@@ -22,18 +22,39 @@ _syscall_invoke_objdir_getmemb(KernelObjectDirectory *dir, uint8_t member, obj_t
}
int
-_syscall_invoke_objdir_nmemb(KernelObjectDirectory *dir, uint8_t *result)
+_syscall_invoke_objdir_lastmemb(KernelObjectDirectory *dir, uint8_t *result)
{
uint8_t *syscallData = _syscall_message_ptr;
int syscall_at = 0;
uint8_t *syscall_result;
SYSCALL_PAYLOAD_PUTOBJ(syscallData, syscall_at, dir);
- SYSCALL_PAYLOAD_PUTL(syscallData, syscall_at, INVOKE_OBJDIR_NMEMB, uint8_t);
+ SYSCALL_PAYLOAD_PUTL(syscallData, syscall_at, INVOKE_OBJDIR_LASTMEMB, uint8_t);
SYSCALL_PAYLOAD_SAVEPTR(syscallData, syscall_at, uint8_t, syscall_result);
int status = _syscall_invoke();
*result = *syscall_result;
-
return status;
}
+
+int
+_syscall_invoke_objdir_move(
+ KernelObjectDirectory *dir,
+ uint8_t memb,
+ KernelObjectDirectory *dest_dir,
+ uint8_t dest_memb)
+{
+ uint8_t *syscallData = _syscall_message_ptr;
+ int syscall_at = 0;
+
+ SYSCALL_PAYLOAD_PUTOBJ(syscallData, syscall_at, dir);
+ SYSCALL_PAYLOAD_PUTL(syscallData, syscall_at, INVOKE_OBJDIR_MOVE, uint8_t);
+ SYSCALL_PAYLOAD_PUTL(syscallData, syscall_at, memb, uint8_t);
+
+ size_t *dest_pathw = (size_t*)(syscallData + syscall_at);
+ SYSCALL_PAYLOAD_PUTOBJ(syscallData, syscall_at, dest_dir);
+ (*dest_pathw)++;
+ SYSCALL_PAYLOAD_PUTL(syscallData, syscall_at, dest_memb, uint8_t);
+
+ return _syscall_invoke();
+}
diff --git a/sysroot/boot/initrd.tar b/sysroot/boot/initrd.tar
index b893e9b..171b978 100644
--- a/sysroot/boot/initrd.tar
+++ b/sysroot/boot/initrd.tar
Binary files differ