diff options
author | Jon Santmyer <jon@jonsantmyer.com> | 2025-08-10 15:46:33 -0400 |
---|---|---|
committer | Jon Santmyer <jon@jonsantmyer.com> | 2025-08-10 15:46:33 -0400 |
commit | 65ba015d6c1f248d36ad01a653bc49637804b15b (patch) | |
tree | a77c3fb3ca7ecac8f65eb9638d152f1e90307d0a | |
download | jove-os-65ba015d6c1f248d36ad01a653bc49637804b15b.tar.gz jove-os-65ba015d6c1f248d36ad01a653bc49637804b15b.tar.bz2 jove-os-65ba015d6c1f248d36ad01a653bc49637804b15b.zip |
working usermode objdir iteration
54 files changed, 1580 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..676fa0e --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +*.a +*.o +*.elf +*.hdd +.ccls* +tools +ovmf* +limine +.cache +sysroot/usr +sysroot/lib +initrd/archive diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..46609a0 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "kernel"] + path = kernel + url = https://git.jonsantmyer.com/jove-kernel diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b63fa27 --- /dev/null +++ b/Makefile @@ -0,0 +1,70 @@ +include config.mk + +KERNEL_BIN := $(KERNELDIR)/jove.elf +INITRD_TAR := $(SYSROOTDIR)/boot/initrd.tar + +TEST_HDD := $(PWD)/test.hdd +TEST_HDD_SIZEM = 64 +TEST_HDD_DIR := $(PWD)/test_hdd + +all: $(KERNEL_BIN) + +.PHONY: clean +clean: + $(MAKE) -C $(KERNELDIR) clean CONFIG=$(PWD)/config.mk + -rm $(STATICLIBS) + -rm $(APPS) + $(foreach dir, $(filter %/, $(wildcard $(APPSDIR)/*/)), $(MAKE) -C $(dir) clean CONFIG=$(PWD)/config.mk) + $(foreach dir, $(filter %/, $(wildcard $(LIBDIR)/*/)), $(MAKE) -C $(dir) clean CONFIG=$(PWD)/config.mk) + +.PHONY: $(KERNEL_BIN) +$(KERNEL_BIN): + $(MAKE) -C $(KERNELDIR) CONFIG=$(PWD)/config.mk + +.PHONY: $(INITRD_TAR) +$(INITRD_TAR): $(APPS) + $(MAKE) -C $(INITRDDIR) CONFIG=$(PWD)/config.mk OUT=$(INITRD_TAR) + +$(INITRDDIR)/files/bin/% : $(STATICLIBS) FORCE + $(MAKE) -C $(APPSDIR)/$(subst $(INITRDDIR)/files/bin/,,$@) CONFIG=$(PWD)/config.mk OUT=$(INITRDDIR)/files/bin + +$(SYSROOTDIR)/lib/%.a : $(SYSROOTDIR) FORCE + $(MAKE) -C $(LIBDIR)/$(subst $(SYSROOTDIR)/lib/,,$(subst .a,,$@)) CONFIG=$(PWD)/config.mk OUT=$(SYSROOTDIR)/lib + +.PHONY: $(SYSROOTDIR)/usr/include +$(SYSROOTDIR)/usr/include: + rm -rf $(SYSROOTDIR)/usr/include + cp -r $(LIBDIR)/libc-headless/include $(SYSROOTDIR)/usr/include + cp -r $(KERNELDIR)/include/ $(SYSROOTDIR)/usr/include/kernel + cp -r $(LIBDIR)/libjove/include $(SYSROOTDIR)/usr/include/jove + +$(SYSROOTDIR): $(SYSROOTDIR)/usr/include + +.PHONY: test +.ONESHELL: +test: $(TEST_HDD) $(KERNEL_BIN) $(INITRD_TAR) $(SYSROOTDIR) + sudo rm -rf $(TEST_HDD_DIR) + mkdir -p $(TEST_HDD_DIR) + export LOOPBACK_DEV=$(shell sudo losetup -Pf --show $(TEST_HDD)) + sudo partprobe $$LOOPBACK_DEV + sudo mkfs.fat -F 32 "$$LOOPBACK_DEV"p1 + sudo mount "$$LOOPBACK_DEV"p1 $(TEST_HDD_DIR) + sudo cp -r $(SYSROOTDIR)/* $(TEST_HDD_DIR) + sudo cp $(KERNEL_BIN) $(TEST_HDD_DIR)/boot + sudo cp limine/limine.exe $(TEST_HDD_DIR)/boot + sudo mkdir -p $(TEST_HDD_DIR)/EFI/BOOT + sudo cp limine/BOOTX64.EFI $(TEST_HDD_DIR)/EFI/BOOT + sync + 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 + +.PHONY: $(TEST_HDD) +$(TEST_HDD): + rm -f $(TEST_HDD) + dd if=/dev/zero bs=1M count=0 seek=$(TEST_HDD_SIZEM) of=$(TEST_HDD) + parted -s $(TEST_HDD) mklabel gpt + parted -s $(TEST_HDD) mkpart primary 2048s 100% + +FORCE: ; diff --git a/apps/init/Makefile b/apps/init/Makefile new file mode 100644 index 0000000..642ca38 --- /dev/null +++ b/apps/init/Makefile @@ -0,0 +1,21 @@ +include $(CONFIG) + +CFILES := $(wildcard *.c) +OFILES := $(patsubst %.c,%.o,$(CFILES)) +OFILES += $(STATICLIBS) + +CFLAGS := -ffreestanding -nostdlib -g +LDFLAGS := -T $(TARGET_MACHINE).ld +OCFLAGS := -O binary \ + --set-section-flags .bss=alloc,load,contents + +all: $(OFILES) + $(LD) $(LDFLAGS) ${OFILES} -o init.elf + objcopy $(OCFLAGS) init.elf $(OUT)/init + +clean: + -rm ${OFILES} + -rm init.elf + +%.o:%.c + $(CC) $(CFLAGS) -c $< -o $@ diff --git a/apps/init/main.c b/apps/init/main.c new file mode 100644 index 0000000..c8dabdf --- /dev/null +++ b/apps/init/main.c @@ -0,0 +1,103 @@ +#include <stdint.h> +#include <string.h> +#include <kernel/object.h> +#include <jove/jove.h> +#include <jove/object.h> +#include <jove/syscall.h> +#include <jove/arch/x86_64/object-pagemap.h> + +/**This program acts as a memory and process server.*/ + +#define INIT_HEAP_START_BYTES 4096 +__attribute__((section(".bss.heap"))) +uint8_t init_heap[INIT_HEAP_START_BYTES]; +size_t init_heap_start = (uintptr_t)init_heap; + +__attribute__((noreturn)) +static void +spin_fail(void) +{ + for(;;); +} + +void* +init_bumpalloc(size_t bytes) +{ + void *r = (void*)init_heap_start; + init_heap_start += 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); + } +} + +void +main(init_data_t *init_data) +{ + libjove_init( + (uintmax_t)init_data->message_object, + (void*)init_data->message_object_address); + jove_kprintf("Hello, Userland!\n"); + + s_populate_rootdir(init_data); + + 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 new file mode 100644 index 0000000..61d16d6 --- /dev/null +++ b/apps/init/memory.h @@ -0,0 +1,6 @@ +#ifndef _INIT_MEMORY_H +#define _INIT_MEMORY_H 1 + + + +#endif diff --git a/apps/init/x86_64.ld b/apps/init/x86_64.ld new file mode 100644 index 0000000..45b08f5 --- /dev/null +++ b/apps/init/x86_64.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/compile_commands.json b/compile_commands.json new file mode 100644 index 0000000..83764f8 --- /dev/null +++ b/compile_commands.json @@ -0,0 +1,62 @@ +[ + { + "directory": "/home/jon/prg/jove/kernel", + "arguments": [ + "/home/jon/prg/jove/tools/bin/x86_64-jove-gcc", + "-ffreestanding", + "-mno-sse", + "-nostdlib", + "-fno-pie", + "-fno-pic", + "-g", + "-D__x86_64__", + "-D__limine__", + "-Iinclude", + "-I.", + "-mno-red-zone", + "-mcmodel=kernel", + "-mfsgsbase", + "-DKERNEL_STACKBYTES=4096", + "-DENABLE_PORTIO_UART", + "-DENABLE_UART", + "-DENABLE_INITRD", + "-DDBG_MEM", + "-c", + "main.c", + "-o", + "main.o" + ], + "file": "main.c" + }, + { + "directory": "/home/jon/prg/jove/apps/init/", + "arguments": [ + "/home/jon/prg/jove/tools/bin/x86_64-jove-gcc", + "-ffreestanding", + "-mno-sse", + "-nostdlib", + "-fno-pie", + "-fno-pic", + "-g", + "-I/home/jon/prg/jove/sysroot/usr/include", + "-c", + "main.c", + "-o", + "main.o" + ], + "file": "main.c" + }, + { + "directory": "/home/jon/prg/jove/lib/libjove/", + "arguments": [ + "/home/jon/prg/jove/tools/bin/x86_64-jove-gcc", + "-ffreestanding", + "-mno-sse", + "-nostdlib", + "-g", + "-I/home/jon/prg/jove/sysroot/usr/include", + "-Iinclude" + ], + "file": "libjove.c" + } +] diff --git a/config.mk b/config.mk new file mode 100644 index 0000000..1659c3a --- /dev/null +++ b/config.mk @@ -0,0 +1,26 @@ +TOOLSDIR := $(PWD)/tools +KERNELDIR := $(PWD)/kernel +SYSROOTDIR := $(PWD)/sysroot +APPSDIR := $(PWD)/apps +INITRDDIR := $(PWD)/initrd +LIBDIR := $(PWD)/lib + +LIMINE_VERSION := 8.x +LIMINE_ORIGIN := https://github.com/limine-bootloader/limine.git +LIMINE_DIR := $(PWD)/limine +LIMINE_GETCMD := git clone $(LIMINE_ORIGIN) --branch=v$(LIMINE_VERSION)-binary --depth 1 $(LIMINE_DIR) + +TARGET_MACHINE = x86_64 +TARGET_OS = jove +TARGET_TRIPLET = $(TARGET_MACHINE)-$(TARGET_OS) +TARGET_BOOTLOADER = limine + +APPS := $(INITRDDIR)/files/bin/init + +STATICLIBS := $(SYSROOTDIR)/lib/libjove.a \ + $(SYSROOTDIR)/lib/libc-headless.a + +CC := $(TOOLSDIR)/bin/$(TARGET_TRIPLET)-gcc +LD := $(TOOLSDIR)/bin/$(TARGET_TRIPLET)-ld +AS := $(TOOLSDIR)/bin/$(TARGET_TRIPLET)-as +AR := $(TOOLSDIR)/bin/$(TARGET_TRIPLET)-ar diff --git a/initrd/Makefile b/initrd/Makefile new file mode 100644 index 0000000..bd4956d --- /dev/null +++ b/initrd/Makefile @@ -0,0 +1,12 @@ +include $(CONFIG) + +FILESDIR := files +ARCHIVEDIR := archive + +all: $(ARCHIVEDIR) + tar -cf $(OUT) -C $(ARCHIVEDIR) . + +.PHONY: $(ARCHIVEDIR) +$(ARCHIVEDIR): + rm -rf $(ARCHIVEDIR) + cp -r $(FILESDIR)/ $(ARCHIVEDIR)/ diff --git a/initrd/files/bin/init b/initrd/files/bin/init Binary files differnew file mode 100755 index 0000000..6fa149d --- /dev/null +++ b/initrd/files/bin/init diff --git a/initrd/initrd.tar b/initrd/initrd.tar Binary files differnew file mode 100644 index 0000000..c684cd9 --- /dev/null +++ b/initrd/initrd.tar diff --git a/kernel b/kernel new file mode 160000 +Subproject c4f8ef91f18d854a4ede7a94e95b2eab898d696 diff --git a/lib/libc-headless/Makefile b/lib/libc-headless/Makefile new file mode 100644 index 0000000..59de6c8 --- /dev/null +++ b/lib/libc-headless/Makefile @@ -0,0 +1,15 @@ +include $(CONFIG) + +CDIRS := stdio ctype string + +CFILES += $(foreach dir,$(CDIRS),$(wildcard $(dir)/*.c)) + +OFILES := $(patsubst %.c,%.o,$(CFILES)) + +CFLAGS := -ffreestanding -nostdlib + +all: ${OFILES} + ar rcs $(OUT)/libc-headless.a $(OFILES) + +%.o:%.c + $(CC) $(CFLAGS) -c $< -o $@ diff --git a/lib/libc-headless/ctype/toupper.c b/lib/libc-headless/ctype/toupper.c new file mode 100644 index 0000000..fe1e1e2 --- /dev/null +++ b/lib/libc-headless/ctype/toupper.c @@ -0,0 +1,9 @@ +#include <ctype.h> + +/* TODO: Faster toupper */ +int +toupper(int c) +{ + if(c >= 'a' && c <= 'z') c += 'A' - 'a'; + return c; +} diff --git a/lib/libc-headless/include/ctype.h b/lib/libc-headless/include/ctype.h new file mode 100644 index 0000000..9dfcc3b --- /dev/null +++ b/lib/libc-headless/include/ctype.h @@ -0,0 +1,7 @@ +#ifndef _CTYPE_H +#define _CTYPE_H 1 + +int toupper(int c); +int tolower(int c); + +#endif diff --git a/lib/libc-headless/include/errno.h b/lib/libc-headless/include/errno.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/lib/libc-headless/include/errno.h diff --git a/lib/libc-headless/include/stdint.h b/lib/libc-headless/include/stdint.h new file mode 100644 index 0000000..165a201 --- /dev/null +++ b/lib/libc-headless/include/stdint.h @@ -0,0 +1,319 @@ +/* Copyright (C) 1997-2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +/* + * ISO C99: 7.18 Integer types <stdint.h> + */ + +#ifndef _STDINT_H +#define _STDINT_H 1 + +#define __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION +#include <bits/libc-header-start.h> +#include <bits/types.h> +#include <bits/wchar.h> +#include <bits/wordsize.h> + +/* Exact integral types. */ + +/* Signed. */ +#include <bits/stdint-intn.h> + +/* Unsigned. */ +#include <bits/stdint-uintn.h> + + +/* Small types. */ + +/* Signed. */ +typedef __int_least8_t int_least8_t; +typedef __int_least16_t int_least16_t; +typedef __int_least32_t int_least32_t; +typedef __int_least64_t int_least64_t; + +/* Unsigned. */ +typedef __uint_least8_t uint_least8_t; +typedef __uint_least16_t uint_least16_t; +typedef __uint_least32_t uint_least32_t; +typedef __uint_least64_t uint_least64_t; + + +/* Fast types. */ + +/* Signed. */ +typedef signed char int_fast8_t; +#if __WORDSIZE == 64 +typedef long int int_fast16_t; +typedef long int int_fast32_t; +typedef long int int_fast64_t; +#else +typedef int int_fast16_t; +typedef int int_fast32_t; +__extension__ +typedef long long int int_fast64_t; +#endif + +/* Unsigned. */ +typedef unsigned char uint_fast8_t; +#if __WORDSIZE == 64 +typedef unsigned long int uint_fast16_t; +typedef unsigned long int uint_fast32_t; +typedef unsigned long int uint_fast64_t; +#else +typedef unsigned int uint_fast16_t; +typedef unsigned int uint_fast32_t; +__extension__ +typedef unsigned long long int uint_fast64_t; +#endif + + +/* Types for `void *' pointers. */ +#if __WORDSIZE == 64 +# ifndef __intptr_t_defined +typedef long int intptr_t; +# define __intptr_t_defined +# endif +typedef unsigned long int uintptr_t; +#else +# ifndef __intptr_t_defined +typedef int intptr_t; +# define __intptr_t_defined +# endif +typedef unsigned int uintptr_t; +#endif + + +/* Largest integral types. */ +typedef __intmax_t intmax_t; +typedef __uintmax_t uintmax_t; + + +# if __WORDSIZE == 64 +# define __INT64_C(c) c ## L +# define __UINT64_C(c) c ## UL +# else +# define __INT64_C(c) c ## LL +# define __UINT64_C(c) c ## ULL +# endif + +/* Limits of integral types. */ + +/* Minimum of signed integral types. */ +# define INT8_MIN (-128) +# define INT16_MIN (-32767-1) +# define INT32_MIN (-2147483647-1) +# define INT64_MIN (-__INT64_C(9223372036854775807)-1) +/* Maximum of signed integral types. */ +# define INT8_MAX (127) +# define INT16_MAX (32767) +# define INT32_MAX (2147483647) +# define INT64_MAX (__INT64_C(9223372036854775807)) + +/* Maximum of unsigned integral types. */ +# define UINT8_MAX (255) +# define UINT16_MAX (65535) +# define UINT32_MAX (4294967295U) +# define UINT64_MAX (__UINT64_C(18446744073709551615)) + + +/* Minimum of signed integral types having a minimum size. */ +# define INT_LEAST8_MIN (-128) +# define INT_LEAST16_MIN (-32767-1) +# define INT_LEAST32_MIN (-2147483647-1) +# define INT_LEAST64_MIN (-__INT64_C(9223372036854775807)-1) +/* Maximum of signed integral types having a minimum size. */ +# define INT_LEAST8_MAX (127) +# define INT_LEAST16_MAX (32767) +# define INT_LEAST32_MAX (2147483647) +# define INT_LEAST64_MAX (__INT64_C(9223372036854775807)) + +/* Maximum of unsigned integral types having a minimum size. */ +# define UINT_LEAST8_MAX (255) +# define UINT_LEAST16_MAX (65535) +# define UINT_LEAST32_MAX (4294967295U) +# define UINT_LEAST64_MAX (__UINT64_C(18446744073709551615)) + + +/* Minimum of fast signed integral types having a minimum size. */ +# define INT_FAST8_MIN (-128) +# if __WORDSIZE == 64 +# define INT_FAST16_MIN (-9223372036854775807L-1) +# define INT_FAST32_MIN (-9223372036854775807L-1) +# else +# define INT_FAST16_MIN (-2147483647-1) +# define INT_FAST32_MIN (-2147483647-1) +# endif +# define INT_FAST64_MIN (-__INT64_C(9223372036854775807)-1) +/* Maximum of fast signed integral types having a minimum size. */ +# define INT_FAST8_MAX (127) +# if __WORDSIZE == 64 +# define INT_FAST16_MAX (9223372036854775807L) +# define INT_FAST32_MAX (9223372036854775807L) +# else +# define INT_FAST16_MAX (2147483647) +# define INT_FAST32_MAX (2147483647) +# endif +# define INT_FAST64_MAX (__INT64_C(9223372036854775807)) + +/* Maximum of fast unsigned integral types having a minimum size. */ +# define UINT_FAST8_MAX (255) +# if __WORDSIZE == 64 +# define UINT_FAST16_MAX (18446744073709551615UL) +# define UINT_FAST32_MAX (18446744073709551615UL) +# else +# define UINT_FAST16_MAX (4294967295U) +# define UINT_FAST32_MAX (4294967295U) +# endif +# define UINT_FAST64_MAX (__UINT64_C(18446744073709551615)) + + +/* Values to test for integral types holding `void *' pointer. */ +# if __WORDSIZE == 64 +# define INTPTR_MIN (-9223372036854775807L-1) +# define INTPTR_MAX (9223372036854775807L) +# define UINTPTR_MAX (18446744073709551615UL) +# else +# define INTPTR_MIN (-2147483647-1) +# define INTPTR_MAX (2147483647) +# define UINTPTR_MAX (4294967295U) +# endif + + +/* Minimum for largest signed integral type. */ +# define INTMAX_MIN (-__INT64_C(9223372036854775807)-1) +/* Maximum for largest signed integral type. */ +# define INTMAX_MAX (__INT64_C(9223372036854775807)) + +/* Maximum for largest unsigned integral type. */ +# define UINTMAX_MAX (__UINT64_C(18446744073709551615)) + + +/* Limits of other integer types. */ + +/* Limits of `ptrdiff_t' type. */ +# if __WORDSIZE == 64 +# define PTRDIFF_MIN (-9223372036854775807L-1) +# define PTRDIFF_MAX (9223372036854775807L) +# else +# if __WORDSIZE32_PTRDIFF_LONG +# define PTRDIFF_MIN (-2147483647L-1) +# define PTRDIFF_MAX (2147483647L) +# else +# define PTRDIFF_MIN (-2147483647-1) +# define PTRDIFF_MAX (2147483647) +# endif +# endif + +/* Limits of `sig_atomic_t'. */ +# define SIG_ATOMIC_MIN (-2147483647-1) +# define SIG_ATOMIC_MAX (2147483647) + +/* Limit of `size_t' type. */ +# if __WORDSIZE == 64 +# define SIZE_MAX (18446744073709551615UL) +# else +# if __WORDSIZE32_SIZE_ULONG +# define SIZE_MAX (4294967295UL) +# else +# define SIZE_MAX (4294967295U) +# endif +# endif + +/* Limits of `wchar_t'. */ +# ifndef WCHAR_MIN +/* These constants might also be defined in <wchar.h>. */ +# define WCHAR_MIN __WCHAR_MIN +# define WCHAR_MAX __WCHAR_MAX +# endif + +/* Limits of `wint_t'. */ +# define WINT_MIN (0u) +# define WINT_MAX (4294967295u) + +/* Signed. */ +# define INT8_C(c) c +# define INT16_C(c) c +# define INT32_C(c) c +# if __WORDSIZE == 64 +# define INT64_C(c) c ## L +# else +# define INT64_C(c) c ## LL +# endif + +/* Unsigned. */ +# define UINT8_C(c) c +# define UINT16_C(c) c +# define UINT32_C(c) c ## U +# if __WORDSIZE == 64 +# define UINT64_C(c) c ## UL +# else +# define UINT64_C(c) c ## ULL +# endif + +/* Maximal type. */ +# if __WORDSIZE == 64 +# define INTMAX_C(c) c ## L +# define UINTMAX_C(c) c ## UL +# else +# define INTMAX_C(c) c ## LL +# define UINTMAX_C(c) c ## ULL +# endif + +#if __GLIBC_USE (IEC_60559_BFP_EXT_C2X) + +# define INT8_WIDTH 8 +# define UINT8_WIDTH 8 +# define INT16_WIDTH 16 +# define UINT16_WIDTH 16 +# define INT32_WIDTH 32 +# define UINT32_WIDTH 32 +# define INT64_WIDTH 64 +# define UINT64_WIDTH 64 + +# define INT_LEAST8_WIDTH 8 +# define UINT_LEAST8_WIDTH 8 +# define INT_LEAST16_WIDTH 16 +# define UINT_LEAST16_WIDTH 16 +# define INT_LEAST32_WIDTH 32 +# define UINT_LEAST32_WIDTH 32 +# define INT_LEAST64_WIDTH 64 +# define UINT_LEAST64_WIDTH 64 + +# define INT_FAST8_WIDTH 8 +# define UINT_FAST8_WIDTH 8 +# define INT_FAST16_WIDTH __WORDSIZE +# define UINT_FAST16_WIDTH __WORDSIZE +# define INT_FAST32_WIDTH __WORDSIZE +# define UINT_FAST32_WIDTH __WORDSIZE +# define INT_FAST64_WIDTH 64 +# define UINT_FAST64_WIDTH 64 + +# define INTPTR_WIDTH __WORDSIZE +# define UINTPTR_WIDTH __WORDSIZE + +# define INTMAX_WIDTH 64 +# define UINTMAX_WIDTH 64 + +# define PTRDIFF_WIDTH __WORDSIZE +# define SIG_ATOMIC_WIDTH 32 +# define SIZE_WIDTH __WORDSIZE +# define WCHAR_WIDTH 32 +# define WINT_WIDTH 32 + +#endif + +#endif /* stdint.h */ diff --git a/lib/libc-headless/include/stdio.h b/lib/libc-headless/include/stdio.h new file mode 100644 index 0000000..cd29004 --- /dev/null +++ b/lib/libc-headless/include/stdio.h @@ -0,0 +1,32 @@ +#ifndef _STDIO_H +#define _STDIO_H 1 + +#include <stdarg.h> +#include <stddef.h> + +#define SEEK_SET 0 +typedef struct { int unused; } FILE; + +extern FILE *stderr; +#define stderr stderr + +int fclose(FILE *file); +int fflush(FILE *file); +FILE *fopen(const char *path, const char *flags); + +size_t fread(void *buf, size_t size, size_t nmemb, FILE* file); +int fseek(FILE *file, long offset, int whence); +long ftell(FILE *file); +size_t fwrite(const void *buf, size_t size, size_t nmemb, FILE *file); +void setbuf(FILE *file, char *buf); + +int fprintf(FILE *file, const char *fmt, ...); +int vfprintf(FILE *file, const char *fmt, va_list ap); + +int sprintf(char *restrict str, const char *restrict format, ...); +int vsprintf(char *restrict str, const char *restrict format, va_list ap); + +int snprintf(char *restrict str, size_t size, const char *restrict format, ...); +int vsnprintf(char *restrict str, size_t size, const char *restrict format, va_list ap); + +#endif diff --git a/lib/libc-headless/include/stdlib.h b/lib/libc-headless/include/stdlib.h new file mode 100644 index 0000000..f29cce7 --- /dev/null +++ b/lib/libc-headless/include/stdlib.h @@ -0,0 +1,17 @@ +#ifndef _STDLIB_H +#define _STDLIB_H 1 + +#include <stddef.h> + +__attribute__((noreturn)) void abort(void); +int atexit(void (*callback)(void)); + +int atoi(const char*); + +void free(void *ptr); +void *malloc(size_t size); +void *calloc(size_t nmemb, size_t size); + +char *getenv(const char *key); + +#endif diff --git a/lib/libc-headless/include/string.h b/lib/libc-headless/include/string.h new file mode 100644 index 0000000..d55bc37 --- /dev/null +++ b/lib/libc-headless/include/string.h @@ -0,0 +1,11 @@ +#ifndef _STRING_H +#define _STRING_H 1 + +#include <stddef.h> + +void *memcpy(void *dest, const void *src, size_t size); +void *memset(void *dest, int byte, size_t size); +char *strcpy(char *dest, const char *src); +size_t strlen(const char *str); + +#endif diff --git a/lib/libc-headless/include/sys/types.h b/lib/libc-headless/include/sys/types.h new file mode 100644 index 0000000..058c38a --- /dev/null +++ b/lib/libc-headless/include/sys/types.h @@ -0,0 +1,6 @@ +#ifndef _SYS_TYPES_H +#define _SYS_TYPES_H 1 + +typedef int pid_t; + +#endif diff --git a/lib/libc-headless/include/time.h b/lib/libc-headless/include/time.h new file mode 100644 index 0000000..c73ee97 --- /dev/null +++ b/lib/libc-headless/include/time.h @@ -0,0 +1,4 @@ +#ifndef _TIME_H +#define _TIME_H 1 + +#endif diff --git a/lib/libc-headless/include/unistd.h b/lib/libc-headless/include/unistd.h new file mode 100644 index 0000000..4e14be9 --- /dev/null +++ b/lib/libc-headless/include/unistd.h @@ -0,0 +1,11 @@ +#ifndef _UNISTD_H +#define _UNISTD_H 1 + +#include <sys/types.h> + +int execv(const char *pathname, char *const argv[]); +int execve(const char *pathname, char *const argv[], char *const envp[]); +int execvp(const char *pathname, char *const argv[]); +pid_t fork(void); + +#endif diff --git a/lib/libc-headless/stdio/sprintf.c b/lib/libc-headless/stdio/sprintf.c new file mode 100644 index 0000000..2881bd5 --- /dev/null +++ b/lib/libc-headless/stdio/sprintf.c @@ -0,0 +1,124 @@ +#include <stdio.h> +#include <stdarg.h> +#include <stdbool.h> +#include <stdint.h> +#include <ctype.h> + +#define VSNPRINTF_PUTC(c) if(size > written) str[written++] = c; else written++ + +int +vsnprintf(char *restrict str, size_t size, const char *restrict format, va_list ap) +{ + int written = 0; + for(int fmti = 0; format[fmti] != 0; fmti++) { + char fmtc = format[fmti]; + if(fmtc != '%') { + VSNPRINTF_PUTC(fmtc); + continue; + } + + /* Flags */ + bool alternate = false; + bool zeropad = false; + bool leftadj = false; + bool signspace = false; + bool showplus = false; + fmtc = format[++fmti]; + + switch(fmtc) { + case '#': alternate = true; fmti++; break; + case '0': zeropad = true; fmti++; break; + case '-': leftadj = true; fmti++; break; + case ' ': signspace = true; fmti++; break; + case '+': showplus = true; fmti++; break; + default: break; + } + + /* Field width. */ + fmtc = format[fmti]; + //TODO: Implement field width + + /* Precision. */ + fmtc = format[fmti]; + //TODO: Implement precision + + /* Length modifier */ + fmtc = format[fmti]; + //TODO: Implement length modifier. + + /* Conversion specifier. */ + bool is_signed = true; + bool is_caps = false; + int radix = 10; + fmtc = format[fmti]; + switch(fmtc) + { + case 'X': + is_caps = true; + case 'x': + radix = 16; + case 'u': + is_signed = false; + case 'd': + case 'i': + goto conversion_int; + case 'p': + alternate = true; + radix = 16; + is_signed = false; + is_caps = true; + goto conversion_int; + case '%': + VSNPRINTF_PUTC('%'); + break; + } + continue; + +conversion_int: + { + uintmax_t value = va_arg(ap, uintmax_t); + bool negative = is_signed && (intmax_t)value < 0; + if(negative) value = (uintmax_t)(-(intmax_t)value); + size_t numc = 0; + + /*Count the number of characters to put in the buffer to represent + * the value in ASCII.*/ + for(uintmax_t v = value; v != 0; v /= radix, numc++); + if(numc == 0) numc++; + + /* Reserve space for alternate repersentation.*/ + if(showplus && !negative) { VSNPRINTF_PUTC('+'); } + if(negative) { VSNPRINTF_PUTC('-'); } + if(signspace && !negative) { VSNPRINTF_PUTC(' '); } + if(alternate) { + VSNPRINTF_PUTC('0'); + if(radix == 16) { + VSNPRINTF_PUTC('x'); + } + if(alternate && radix == 2) { + VSNPRINTF_PUTC('b'); + } + } + + /* Try to put characters into the buffer*/ + if(value == 0) { + VSNPRINTF_PUTC('0'); + } + else { + 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'); + if(is_caps) c = toupper(c); + str[written + i] = c; + } + written += numc; + } + continue; + } + } + VSNPRINTF_PUTC(0); + return written - 1; +} + + diff --git a/lib/libc-headless/string/memcpy.c b/lib/libc-headless/string/memcpy.c new file mode 100644 index 0000000..f71444d --- /dev/null +++ b/lib/libc-headless/string/memcpy.c @@ -0,0 +1,10 @@ +#include <stddef.h> + +void* +memcpy(void *dest, const void *src, size_t n) +{ + const unsigned char *s = src; + for(unsigned char *d = dest; n; n--) + *(d++) = *(s++); + return dest; +} diff --git a/lib/libc-headless/string/memset.c b/lib/libc-headless/string/memset.c new file mode 100644 index 0000000..f79a4b4 --- /dev/null +++ b/lib/libc-headless/string/memset.c @@ -0,0 +1,7 @@ +#include <stddef.h> + +void +memset(void *s, int c, size_t n) +{ + for(unsigned char *sb = s; n; n--) *(sb++) = c; +} diff --git a/lib/libjove/Makefile b/lib/libjove/Makefile new file mode 100644 index 0000000..cc5f347 --- /dev/null +++ b/lib/libjove/Makefile @@ -0,0 +1,18 @@ +include $(CONFIG) + +CDIRS := syscall object arch/$(TARGET_MACHINE) +CFILES := $(wildcard *.c) +CFILES += $(foreach dir,$(CDIRS),$(wildcard $(dir)/*.c)) + +OFILES := $(patsubst %.c,%.o,$(CFILES)) + +CFLAGS := -ffreestanding -nostdlib -Iinclude -g + +all: ${OFILES} + ar rcs $(OUT)/libjove.a $(OFILES) + +clean: + -rm $(OFILES) + +%.o:%.c + $(CC) $(CFLAGS) -c $< -o $@ diff --git a/lib/libjove/arch/x86_64/invoke-pagemap.c b/lib/libjove/arch/x86_64/invoke-pagemap.c new file mode 100644 index 0000000..8357904 --- /dev/null +++ b/lib/libjove/arch/x86_64/invoke-pagemap.c @@ -0,0 +1,21 @@ +#include <arch/x86_64/object-pagemap.h> +#include <kernel/syscall.h> +#include <kernel/arch/x86_64/syscall.h> +#include <object.h> +#include <path-fromobj.h> +#include <syscall.h> +#include <jove/jove.h> + +int +_syscall_invoke_mapping_get(KernelObjectPageMapping *mapping, uint16_t pmli, KernelObjectPageMapping *dest) +{ + 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, dest); + + return _syscall_invoke(); +} diff --git a/lib/libjove/include/arch/x86_64/object-pagemap.h b/lib/libjove/include/arch/x86_64/object-pagemap.h new file mode 100644 index 0000000..55b0570 --- /dev/null +++ b/lib/libjove/include/arch/x86_64/object-pagemap.h @@ -0,0 +1,14 @@ +#ifndef _LIBJOVE_ARCH_x86_64_OBJECT_PAGEMAP_H +#define _LIBJOVE_ARCH_x86_64_OBJECT_PAGEMAP_H 1 + +#include <jove/object-typed.h> + +typedef struct KernelObjectPageMapping +{ + KernelObjectTyped typed; + uint8_t level; +} KernelObjectPageMapping; + + + +#endif diff --git a/lib/libjove/include/arch/x86_64/syscall.h b/lib/libjove/include/arch/x86_64/syscall.h new file mode 100644 index 0000000..1d7df53 --- /dev/null +++ b/lib/libjove/include/arch/x86_64/syscall.h @@ -0,0 +1,12 @@ +#ifndef _LIBJOVE_ARCH_x86_64_SYSCALL_H +#define _LIBJOVE_ARCH_x86_64_SYSCALL_H 1 + +#include <stdint.h> + +#include <kernel/object.h> +#include <jove/object-path.h> + +int _syscall_invoke_mapping_get(KernelObjectPath path, uint16_t pmli, KernelObjectPath destPath); + + +#endif diff --git a/lib/libjove/include/jove.h b/lib/libjove/include/jove.h new file mode 100644 index 0000000..2efef3e --- /dev/null +++ b/lib/libjove/include/jove.h @@ -0,0 +1,13 @@ +#ifndef _LIBJOVE_JOVE_H +#define _LIBJOVE_JOVE_H 1 + +#include <stdint.h> + +extern uintmax_t _syscall_message_box; +extern void *_syscall_message_ptr; + +void libjove_init(uintmax_t box, void *boxptr); + +void jove_kprintf(const char *restrict fmt, ...); + +#endif diff --git a/lib/libjove/include/object-dir.h b/lib/libjove/include/object-dir.h new file mode 100644 index 0000000..f258089 --- /dev/null +++ b/lib/libjove/include/object-dir.h @@ -0,0 +1,17 @@ +#ifndef _LIBJOVE_OBJDIR_H +#define _LIBJOVE_OBJDIR_H 1 + +#include <stdint.h> +#include <stddef.h> +#include <kernel/object.h> + +#include <jove/object-typed.h> + +/**@STRUCT Represents a kobjdir.*/ +typedef struct _KernelObjectDirectory { + KernelObjectTyped typed; + KernelObjectTyped *children[256]; +} KernelObjectDirectory; +extern KernelObjectDirectory __rootdir; + +#endif diff --git a/lib/libjove/include/object-message.h b/lib/libjove/include/object-message.h new file mode 100644 index 0000000..a4b7d35 --- /dev/null +++ b/lib/libjove/include/object-message.h @@ -0,0 +1,13 @@ +#ifndef _LIBJOVE_OBJECT_MESSAGE_H +#define _LIBJOVE_OBJECT_MESSAGE_H 1 + +#include <jove/object-typed.h> + +typedef struct _KernelObjectMessage +{ + KernelObjectTyped typed; + uint16_t pages; + void *data; +} KernelObjectMessage; + +#endif diff --git a/lib/libjove/include/object-typed.h b/lib/libjove/include/object-typed.h new file mode 100644 index 0000000..750cf08 --- /dev/null +++ b/lib/libjove/include/object-typed.h @@ -0,0 +1,15 @@ +#ifndef _LIBJOVE_OBJPATH_H +#define _LIBJOVE_OBJPATH_H 1 + +#include <stddef.h> +#include <stdint.h> +#include <kernel/object.h> + +typedef struct KernelObjectTyped +{ + void *parent; + obj_type_t type; + uint8_t membi; +} KernelObjectTyped; + +#endif diff --git a/lib/libjove/include/object-untyped.h b/lib/libjove/include/object-untyped.h new file mode 100644 index 0000000..ea1185d --- /dev/null +++ b/lib/libjove/include/object-untyped.h @@ -0,0 +1,39 @@ +#ifndef _LIBJOVE_OBJECT_UNTYPED_H +#define _LIBJOVE_OBJECT_UNTYPED_H 1 + +#include <jove/object-typed.h> + +/**@STRUCT Represents a KO_MEMOY_UNTYPED*/ +typedef struct KernelObjectUntyped +{ + KernelObjectTyped typed; + size_t bytes, alignment; +} 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); +#endif diff --git a/lib/libjove/include/object.h b/lib/libjove/include/object.h new file mode 100644 index 0000000..5b0cc82 --- /dev/null +++ b/lib/libjove/include/object.h @@ -0,0 +1,11 @@ +#ifndef _LIBJOVE_OBJECT_H +#define _LIBJOVE_OBJECT_H 1 + +#include <jove/object-typed.h> +#include <jove/object-dir.h> +#include <jove/object-untyped.h> +#include <jove/object-message.h> + +#define JOVE_OBJECT_TYPED(o) (KernelObjectTyped*)o + +#endif diff --git a/lib/libjove/include/path-fromobj.h b/lib/libjove/include/path-fromobj.h new file mode 100644 index 0000000..252be29 --- /dev/null +++ b/lib/libjove/include/path-fromobj.h @@ -0,0 +1,13 @@ +#ifndef _LIBJOVE_PATH_FROMOBJ_H +#define _LIBJOVE_PATH_FROMOBJ_H 1 + +#include <jove/object-typed.h> +#include <kernel/object.h> + +int path_fromobj_s(KernelObjectTyped *obj, uint8_t *buffer, int size); +inline int path_fromobj(KernelObjectTyped *obj, uint8_t *buffer) +{ return path_fromobj_s(obj, buffer, -1); } + +int path_tobuf(KernelObjectTyped *obj, uint8_t *buffer, size_t at, size_t bufferw); + +#endif diff --git a/lib/libjove/include/syscall.h b/lib/libjove/include/syscall.h new file mode 100644 index 0000000..432be85 --- /dev/null +++ b/lib/libjove/include/syscall.h @@ -0,0 +1,35 @@ +#ifndef _LIBJOVE_SYSCALL_H +#define _LIBJOVE_SYSCALL_H 1 + +#include <stdint.h> + +#include <kernel/object.h> +#include <jove/object.h> + +#define SYSCALL_PAYLOAD_PUTL(buf, at, v, type) \ + if(at + sizeof(type) > KO_MESSAGE_BYTES) return -1; \ + *((type*)(&buf[at])) = v; \ + at += sizeof(type) + +#define SYSCALL_PAYLOAD_SAVEPTR(buf, at, type, val) \ + if(at + sizeof(type) >= KO_MESSAGE_BYTES) return -1; \ + 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 + + +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_untyped_size(KernelObjectUntyped *untyped, size_t *bytes); +int _syscall_invoke_untyped_split(KernelObjectUntyped *path, size_t bytes, KernelObjectUntyped *dest); +int _syscall_invoke_untyped_merge(KernelObjectUntyped *a, KernelObjectUntyped *b); +int _syscall_invoke_untyped_alignment(KernelObjectUntyped *path, size_t *alignment); + +#endif diff --git a/lib/libjove/kprintf.c b/lib/libjove/kprintf.c new file mode 100644 index 0000000..c04756a --- /dev/null +++ b/lib/libjove/kprintf.c @@ -0,0 +1,16 @@ +#include <jove/jove.h> +#include <jove/syscall.h> +#include <stdio.h> +#include <stdarg.h> + +void +jove_kprintf(const char *restrict fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + char buffer[256]; + vsnprintf(buffer, 256, fmt, ap); + va_end(ap); + + for(char *c = buffer; *c; c++) _syscall_debug_putc(*c); +} diff --git a/lib/libjove/libjove.c b/lib/libjove/libjove.c new file mode 100644 index 0000000..fe1c080 --- /dev/null +++ b/lib/libjove/libjove.c @@ -0,0 +1,11 @@ +#include "include/jove.h" + +uintmax_t _syscall_message_box = 0; +void *_syscall_message_ptr = 0; + +void +libjove_init(uint64_t box, void *boxptr) +{ + _syscall_message_box = box; + _syscall_message_ptr = boxptr; +} diff --git a/lib/libjove/object/directory.c b/lib/libjove/object/directory.c new file mode 100644 index 0000000..a9487e8 --- /dev/null +++ b/lib/libjove/object/directory.c @@ -0,0 +1,4 @@ +#include <object.h> +#include <syscall.h> + +KernelObjectDirectory __rootdir; diff --git a/lib/libjove/syscall/debug_putc.c b/lib/libjove/syscall/debug_putc.c new file mode 100644 index 0000000..2d68ee1 --- /dev/null +++ b/lib/libjove/syscall/debug_putc.c @@ -0,0 +1,13 @@ +#include "jove/syscall.h" +#include "jove/jove.h" +#include <kernel/syscall.h> + +void +_syscall_debug_putc(char c) +{ + *((char*)_syscall_message_ptr) = c; + register uint64_t box asm ("rdi") = _syscall_message_box; + register uint64_t call asm ("rsi") = SYSCALL_DEBUG_PUTC; + + __asm__ volatile("syscall"::: "memory"); +} diff --git a/lib/libjove/syscall/invoke-objdir.c b/lib/libjove/syscall/invoke-objdir.c new file mode 100644 index 0000000..462c282 --- /dev/null +++ b/lib/libjove/syscall/invoke-objdir.c @@ -0,0 +1,39 @@ +#include <jove.h> +#include <object.h> +#include <path-fromobj.h> +#include <syscall.h> +#include <kernel/syscall.h> + +int +_syscall_invoke_objdir_getmemb(KernelObjectDirectory *dir, uint8_t member, obj_type_t *result) +{ + uint8_t *syscallData = _syscall_message_ptr; + int syscall_at = 0; + obj_type_t *syscall_result; + + SYSCALL_PAYLOAD_PUTOBJ(syscallData, syscall_at, dir); + SYSCALL_PAYLOAD_PUTL(syscallData, syscall_at, INVOKE_OBJDIR_GETMEMB, uint8_t); + SYSCALL_PAYLOAD_PUTL(syscallData, syscall_at, member, uint8_t); + SYSCALL_PAYLOAD_SAVEPTR(syscallData, syscall_at, obj_type_t, syscall_result); + + int status = _syscall_invoke(); + *result = *syscall_result; + return status; +} + +int +_syscall_invoke_objdir_nmemb(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_SAVEPTR(syscallData, syscall_at, uint8_t, syscall_result); + + int status = _syscall_invoke(); + *result = *syscall_result; + + return status; +} diff --git a/lib/libjove/syscall/invoke-untyped.c b/lib/libjove/syscall/invoke-untyped.c new file mode 100644 index 0000000..3f718c2 --- /dev/null +++ b/lib/libjove/syscall/invoke-untyped.c @@ -0,0 +1,52 @@ +#include <jove.h> +#include <object.h> +#include <path-fromobj.h> +#include <syscall.h> +#include <kernel/syscall.h> +#include <string.h> + +int +_syscall_invoke_untyped_size(KernelObjectUntyped *untyped, size_t *bytes) +{ + uint8_t *syscallData = _syscall_message_ptr; + int syscall_at = 0; + size_t *syscall_bytes; + + SYSCALL_PAYLOAD_PUTOBJ(syscallData, syscall_at, untyped); + SYSCALL_PAYLOAD_PUTL(syscallData, syscall_at, INVOKE_UNTYPED_SIZE, uint8_t); + SYSCALL_PAYLOAD_SAVEPTR(syscallData, syscall_at, size_t, syscall_bytes); + + int status = _syscall_invoke(); + *bytes = *syscall_bytes; + return status; +} + +int +_syscall_invoke_untyped_split(KernelObjectUntyped *untyped, size_t bytes, KernelObjectUntyped *dest) +{ + uint8_t *syscallData = _syscall_message_ptr; + int syscall_at = 0; + + SYSCALL_PAYLOAD_PUTOBJ(syscallData, syscall_at, untyped); + SYSCALL_PAYLOAD_PUTL(syscallData, syscall_at, INVOKE_UNTYPED_SPLIT, uint8_t); + SYSCALL_PAYLOAD_PUTOBJ(syscallData, syscall_at, dest); + SYSCALL_PAYLOAD_PUTL(syscallData, syscall_at, bytes, size_t); + + return _syscall_invoke(); +} + +int +_syscall_invoke_untyped_alignment(KernelObjectUntyped *untyped, size_t *alignment) +{ + uint8_t *syscallData = _syscall_message_ptr; + int syscall_at = 0; + size_t *syscall_alignment; + + SYSCALL_PAYLOAD_PUTOBJ(syscallData, syscall_at, untyped); + SYSCALL_PAYLOAD_PUTL(syscallData, syscall_at, INVOKE_UNTYPED_ALIGNMENT, uint8_t); + SYSCALL_PAYLOAD_SAVEPTR(syscallData, syscall_at, size_t, syscall_alignment); + + int status = _syscall_invoke(); + *alignment = *syscall_alignment; + return status; +} diff --git a/lib/libjove/syscall/invoke.c b/lib/libjove/syscall/invoke.c new file mode 100644 index 0000000..e673623 --- /dev/null +++ b/lib/libjove/syscall/invoke.c @@ -0,0 +1,14 @@ +#include <syscall.h> +#include <kernel/syscall.h> +#include <jove.h> + +int +_syscall_invoke(void) +{ + register uint64_t box asm ("rdi") = _syscall_message_box; + register uint64_t call asm ("rsi") = SYSCALL_INVOKE; + + int status = 0; + __asm__ volatile("syscall": "=a"(status) :: "memory"); + return status; +} diff --git a/lib/libjove/syscall/path-fromobj.c b/lib/libjove/syscall/path-fromobj.c new file mode 100644 index 0000000..1c0c5d9 --- /dev/null +++ b/lib/libjove/syscall/path-fromobj.c @@ -0,0 +1,33 @@ +#include <path-fromobj.h> + +int +path_fromobj_s(KernelObjectTyped *obj, uint8_t *buffer, int size) +{ + size_t depth = 0, odepth = 0; + for(KernelObjectTyped *o = obj->parent; o; o = o->parent, depth++); + + odepth = depth; + if(depth > size) depth = size; + + for(int i = 0; i < depth; i++) { + buffer[depth - i - 1] = obj->membi; + obj = obj->parent; + } + return odepth; +} + +int +path_tobuf(KernelObjectTyped *obj, uint8_t *buffer, size_t at, size_t bufferw) +{ + if(at + sizeof(size_t) > bufferw) return -1; + + size_t *buffer_pathW = (size_t*)(&buffer[at]); + uint8_t *buffer_path = (uint8_t*)(&buffer_pathW[1]); + + size_t maxDepth = bufferw - (buffer_path - buffer); + size_t objDepth = path_fromobj_s(obj, buffer_path, bufferw - (size_t)(buffer_path - buffer)); + if(objDepth > maxDepth) return -1; + + *buffer_pathW = objDepth; + return (int)(buffer_path - buffer) + objDepth; +} diff --git a/limine.mk b/limine.mk new file mode 100644 index 0000000..796c8bd --- /dev/null +++ b/limine.mk @@ -0,0 +1,9 @@ +LIMINE_VERSION := 6.x +LIMINE_GIT := https://github.com/limine-bootloader/limine.git +LIMINE_DIR := $(PWD)/limine + +all: $(LIMINE_DIR) + +$(LIMINE_DIR): + git clone $(LIMINE_GIT) --branch=v$(LIMINE_VERSION)-branch-binary --depth=1 + diff --git a/scripts/binutils-2.41.diff b/scripts/binutils-2.41.diff new file mode 100644 index 0000000..c63c8c1 --- /dev/null +++ b/scripts/binutils-2.41.diff @@ -0,0 +1,77 @@ +diff -rNau binutils-2.41/bfd/config.bfd binutils-2.41-patched/bfd/config.bfd +--- binutils-2.41/bfd/config.bfd 2023-07-02 19:00:00.000000000 -0400 ++++ binutils-2.41-patched/bfd/config.bfd 2024-03-10 23:19:47.522036207 -0400 +@@ -714,6 +714,13 @@ + targ_selvecs="i386_elf32_vec iamcu_elf32_vec x86_64_elf32_vec i386_pei_vec x86_64_pe_vec x86_64_pei_vec" + want64=true + ;; ++#ifdef BFD64 ++ x86_64-*-jove*) ++ targ_defvec=x86_64_elf64_vec ++ targ_selvecs=i386_elf32_vec ++ want64=true ++ ;; ++#endif + x86_64-*-mingw* | x86_64-*-pe | x86_64-*-pep | x86_64-*-cygwin) + targ_defvec=x86_64_pe_vec + targ_selvecs="x86_64_pe_vec x86_64_pei_vec x86_64_pe_big_vec x86_64_elf64_vec i386_pe_vec i386_pei_vec i386_elf32_vec iamcu_elf32_vec pdb_vec" +diff -rNau binutils-2.41/config.sub binutils-2.41-patched/config.sub +--- binutils-2.41/config.sub 2023-07-02 19:00:00.000000000 -0400 ++++ binutils-2.41-patched/config.sub 2024-03-10 23:33:30.546506756 -0400 +@@ -1758,7 +1758,7 @@ + | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ + | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ + | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \ +- | fiwix* | mlibc* ) ++ | fiwix* | mlibc* | jove* ) + ;; + # This one is extra strict with allowed versions + sco3.2v2 | sco3.2v[4-9]* | sco5v6*) +diff -rNau binutils-2.41/gas/configure.tgt binutils-2.41-patched/gas/configure.tgt +--- binutils-2.41/gas/configure.tgt 2023-07-02 19:00:00.000000000 -0400 ++++ binutils-2.41-patched/gas/configure.tgt 2024-03-10 23:22:33.351797968 -0400 +@@ -231,6 +231,7 @@ + i386-*-haiku*) fmt=elf em=haiku ;; + i386-*-genode*) fmt=elf ;; + i386-*-bsd*) fmt=aout em=386bsd ;; ++ i386-*-jove*) fmt=elf ;; + i386-*-netbsd*-gnu* | \ + i386-*-knetbsd*-gnu | \ + i386-*-netbsd* | \ +diff -rNau binutils-2.41/ld/configure.tgt binutils-2.41-patched/ld/configure.tgt +--- binutils-2.41/ld/configure.tgt 2023-07-02 19:00:00.000000000 -0400 ++++ binutils-2.41-patched/ld/configure.tgt 2024-03-10 23:24:16.838998259 -0400 +@@ -1053,6 +1053,9 @@ + targ_extra_ofiles="deffilep.o pdb.o pep-dll.o pe-dll.o" + test "$targ" != "$host" && LIB_PATH='${tooldir}/lib/w32api' + ;; ++x86_64-*-jove*) targ_emul=elf_x86_64_jove ++ targ_extra_emuls="elf_x86_64" ++ ;; + x86_64-*-mingw*) targ_emul=i386pep ; + targ_extra_emuls=i386pe + targ_extra_ofiles="deffilep.o pdb.o pep-dll.o pe-dll.o" +diff -rNau binutils-2.41/ld/emulparams/elf_x86_64_jove.sh binutils-2.41-patched/ld/emulparams/elf_x86_64_jove.sh +--- binutils-2.41/ld/emulparams/elf_x86_64_jove.sh 1969-12-31 19:00:00.000000000 -0500 ++++ binutils-2.41-patched/ld/emulparams/elf_x86_64_jove.sh 2024-03-10 23:25:24.152469179 -0400 +@@ -0,0 +1 @@ ++source_sh ${srcdir}/emulparams/elf_x86_64.sh +diff -rNau binutils-2.41/ld/Makefile.am binutils-2.41-patched/ld/Makefile.am +--- binutils-2.41/ld/Makefile.am 2023-07-02 19:00:00.000000000 -0400 ++++ binutils-2.41-patched/ld/Makefile.am 2024-03-10 23:26:41.812851367 -0400 +@@ -455,6 +455,7 @@ + eelf64tilegx_be.c \ + eelf_mipsel_haiku.c \ + eelf_x86_64.c \ ++ eelf_x86_64_jove.c \ + eelf_x86_64_cloudabi.c \ + eelf_x86_64_fbsd.c \ + eelf_x86_64_haiku.c \ +@@ -951,6 +951,7 @@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64tilegx_be.Pc@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_mipsel_haiku.Pc@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64.Pc@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64_jove.Pc@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64_cloudabi.Pc@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64_fbsd.Pc@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64_haiku.Pc@am__quote@ diff --git a/scripts/buildtools.mk b/scripts/buildtools.mk new file mode 100644 index 0000000..e3fd46b --- /dev/null +++ b/scripts/buildtools.mk @@ -0,0 +1,63 @@ +BINUTILS_VERSION := 2.41 +GCC_VERSION := 13.2.0 +TOOLCHAIN := x86_64-jove + +TOOLDIR := $(PWD)/tools +SCRIPTDIR := $(PWD)/scripts +TOOL_SRCDIR := $(TOOLDIR)/src +TOOL_BUILDDIR := $(TOOLDIR)/build +SYSROOT_DIR := $(PWD)/sysroot + +BINUTILS_ARCHIVE := binutils-$(BINUTILS_VERSION).tar.gz +BINUTILS_URL := https://ftp.gnu.org/gnu/binutils/$(BINUTILS_ARCHIVE) +BINUTILS_PATCHFILE := $(SCRIPTDIR)/binutils-$(BINUTILS_VERSION).diff +BINUTILS_SRCDIR := $(TOOL_SRCDIR)/binutils-$(BINUTILS_VERSION) +BINUTILS_BUILDDIR := $(TOOL_BUILDDIR)/binutils + +GCC_ARCHIVE := gcc-$(GCC_VERSION).tar.gz +GCC_URL := https://ftp.gnu.org/gnu/gcc/gcc-$(GCC_VERSION)/$(GCC_ARCHIVE) +GCC_PATCHFILE := $(SCRIPTDIR)/gcc-$(GCC_VERSION).diff +GCC_SRCDIR := $(TOOL_SRCDIR)/gcc-$(GCC_VERSION) +GCC_BUILDDIR := $(TOOL_BUILDDIR)/gcc + +all: $(TOOLDIR) $(BINUTILS_BUILDDIR) $(GCC_BUILDDIR) + +.ONESHELL: +$(BINUTILS_BUILDDIR): $(BINUTILS_SRCDIR) + mkdir -p $(BINUTILS_BUILDDIR) + cd $(BINUTILS_BUILDDIR) + $(BINUTILS_SRCDIR)/configure --target=$(TOOLCHAIN) --prefix="$(TOOLDIR)" --with-sysroot=$(SYSROOT_DIR) --disable-werror + make -j4 + make install + +.PHONY: $(GCC_BUILDDIR) +.ONESHELL: +$(GCC_BUILDDIR): $(GCC_SRCDIR) + mkdir -p $(GCC_BUILDDIR) + cd $(GCC_BUILDDIR) + $(GCC_SRCDIR)/configure --target=$(TOOLCHAIN) --prefix="$(TOOLDIR)" --enable-languages=c --with-sysroot=$(SYSROOT_DIR) + make all-gcc -j4 + make all-target-libgcc -j4 + make install-gcc + make install-target-libgcc + +$(BINUTILS_SRCDIR): $(TOOLDIR)/$(BINUTILS_ARCHIVE) + tar -xzvf $(TOOLDIR)/$(BINUTILS_ARCHIVE) -C $(TOOL_SRCDIR) + patch --directory=$(BINUTILS_SRCDIR) --strip=1 < $(BINUTILS_PATCHFILE) + cd $(BINUTILS_SRCDIR)/ld && automake + +$(GCC_SRCDIR): $(TOOLDIR)/$(GCC_ARCHIVE) + tar -xzvf $(TOOLDIR)/$(GCC_ARCHIVE) -C $(TOOL_SRCDIR) + patch --directory=$(GCC_SRCDIR) --strip=1 < $(GCC_PATCHFILE) + cd $(GCC_SRCDIR) && ./contrib/download_prerequisites + +$(TOOLDIR)/$(BINUTILS_ARCHIVE): + wget $(BINUTILS_URL) -O $(TOOLDIR)/$(BINUTILS_ARCHIVE) + +$(TOOLDIR)/$(GCC_ARCHIVE): + wget $(GCC_URL) -O $(TOOLDIR)/$(GCC_ARCHIVE) + +$(TOOLDIR): + mkdir -p $(TOOLDIR) + mkdir -p $(TOOL_SRCDIR) + mkdir -p $(TOOL_BUILDDIR) diff --git a/scripts/gcc-13.2.0.diff b/scripts/gcc-13.2.0.diff new file mode 100644 index 0000000..d32bf9d --- /dev/null +++ b/scripts/gcc-13.2.0.diff @@ -0,0 +1,86 @@ +diff -rNau gcc-13.2.0/config.sub gcc-13.2.0-patched/config.sub +--- gcc-13.2.0/config.sub 2023-07-27 04:13:03.000000000 -0400 ++++ gcc-13.2.0-patched/config.sub 2024-03-10 23:33:56.596289806 -0400 +@@ -1749,7 +1749,7 @@ + | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ + | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ + | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \ +- | fiwix* ) ++ | fiwix* | jove* ) + ;; + # This one is extra strict with allowed versions + sco3.2v2 | sco3.2v[4-9]* | sco5v6*) +diff -rNau gcc-13.2.0/fixincludes/mkfixinc.sh gcc-13.2.0-patched/fixincludes/mkfixinc.sh +--- gcc-13.2.0/fixincludes/mkfixinc.sh 2023-07-27 04:13:03.000000000 -0400 ++++ gcc-13.2.0-patched/fixincludes/mkfixinc.sh 2024-03-10 23:49:24.405547826 -0400 +@@ -20,6 +20,7 @@ + powerpcle-*-eabisim* | \ + powerpcle-*-eabi* | \ + *-*-vxworks7* | \ ++ *-*-jove* | \ + *-musl* ) + # IF there is no include fixing, + # THEN create a no-op fixer and exit +diff -rNau gcc-13.2.0/gcc/config/jove.h gcc-13.2.0-patched/gcc/config/jove.h +--- gcc-13.2.0/gcc/config/jove.h 1969-12-31 19:00:00.000000000 -0500 ++++ gcc-13.2.0-patched/gcc/config/jove.h 2024-03-10 23:44:13.570083205 -0400 +@@ -0,0 +1,17 @@ ++#undef TARGET_JOVE ++#define TARGET_JOVE 1 ++ ++#undef LINK_SPEC ++#define LINK_SPEC "%{shared:-shared} %{static:-static} %{!shared: %{!static: %{rdynamic:-export-dynamic}}}" ++ ++#undef LIB_SPEC ++#define LIB_SPEC "--start-group -lc -ljove --end-group" ++ ++#undef STARTFILE_SPEC ++#define STARTFILE_SPEC "%{!shared: %{!pg:crt0.o%s}} crti.o%s %{!shared:crtbegin.o%s}" ++ ++#undef ENDFILE_SPEC ++#define ENDFILE_SPEC "%{!shared:crtend.o%s} crtn.o%s" ++ ++#undef OBJECT_FORMAT_ELF ++#define OBJECT_FORMAT_ELF +diff -rNau gcc-13.2.0/gcc/config.gcc gcc-13.2.0-patched/gcc/config.gcc +--- gcc-13.2.0/gcc/config.gcc 2023-07-27 04:13:04.000000000 -0400 ++++ gcc-13.2.0-patched/gcc/config.gcc 2024-03-10 23:42:11.659119360 -0400 +@@ -843,6 +843,13 @@ + *-*-fuchsia*) + native_system_header_dir=/include + ;; ++*-*-jove*) ++ gas=yes ++ gnu_ld=yes ++ default_use_cxa_atexit=yes ++ use_gcc_stdint=provide ++ tmake_file="t-slibgcc" ++ ;; + *-*-linux* | frv-*-*linux* | *-*-kfreebsd*-gnu | *-*-gnu* | *-*-kopensolaris*-gnu | *-*-uclinuxfdpiceabi) + extra_options="$extra_options gnu-user.opt" + gas=yes +@@ -1891,6 +1897,10 @@ + x86_64-*-freebsd*) + tm_file="${tm_file} i386/unix.h i386/att.h elfos.h ${fbsd_tm_file} i386/x86-64.h i386/freebsd.h i386/freebsd64.h" + ;; ++x86_64-*-jove*) ++ tm_file="${tm_file} i386/unix.h i386/att.h elfos.h i386/i386elf.h i386/x86-64.h jove.h glibc-stdint.h" ++ tmake_file="${tmake_file} t-slibgcc" ++ ;; + i[34567]86-*-netbsdelf*) + tm_file="${tm_file} i386/unix.h i386/att.h elfos.h ${nbsd_tm_file} i386/netbsd-elf.h" + extra_options="${extra_options} netbsd.opt netbsd-elf.opt" +diff -rNau gcc-13.2.0/libgcc/config.host gcc-13.2.0-patched/libgcc/config.host +--- gcc-13.2.0/libgcc/config.host 2023-07-27 04:13:07.000000000 -0400 ++++ gcc-13.2.0-patched/libgcc/config.host 2024-03-10 23:47:32.669386544 -0400 +@@ -386,6 +386,10 @@ + esac + + case ${host} in ++x86_64-*-jove*) ++ tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic t-libgcc-pic t-slibgcc t-slibgcc-gld t-slibgcc-elf-ver" ++ extra_parts="$extra_parts crti.o crtbegin.o crtend.o crtn.o" ++ ;; + aarch64*-*-elf | aarch64*-*-rtems*) + extra_parts="$extra_parts crtbegin.o crtend.o crti.o crtn.o" + extra_parts="$extra_parts crtfastmath.o" diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..f59b6de --- /dev/null +++ b/shell.nix @@ -0,0 +1,30 @@ +{ pkgs ? import <nixpkgs> {} }: +pkgs.mkShell { + name = "jove-build-env"; + buildInputs = with pkgs; [ + # Library depends + gmp gmp.dev + isl + libffi libffi.dev + libmpc + libxcrypt + mpfr mpfr.dev + xz xz.dev + zlib zlib.dev + + m4 + bison + flex + texinfo + automake115x + autoconf269 + + gcc + stdenv.cc + stdenv.cc.libc stdenv.cc.libc_dev + + # Test suite + qemu_kvm + parted + ]; +} diff --git a/sysroot/boot/initrd.tar b/sysroot/boot/initrd.tar Binary files differnew file mode 100644 index 0000000..b893e9b --- /dev/null +++ b/sysroot/boot/initrd.tar diff --git a/sysroot/boot/limine.conf b/sysroot/boot/limine.conf new file mode 100644 index 0000000..cfe1d54 --- /dev/null +++ b/sysroot/boot/limine.conf @@ -0,0 +1,15 @@ +${KERNEL}=boot():/boot/jove.elf +${INITRD}=boot():/boot/initrd.tar + +default_entry: 1 +timeout: 0 +verbose: yes + +/Jove + protocol: limine + kaslr: no + + path: ${KERNEL} + cmdline: initrd=/boot/initrd.tar init=/bin/init + + module_path: ${INITRD} |