summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2024-03-17 20:59:31 -0400
committerIan Moffett <ian@osmora.org>2024-03-17 20:59:31 -0400
commit0776264c266e7c1619b8b8b84d2da5384979bb3c (patch)
tree80b6ded012336e24c72cc2c16e4c3ce952b7b739
parent7895aaff402a021a1b04645ca8d251f760e5662e (diff)
parent2896f4126de2ee0fd1bab4b960bfb2213c359f18 (diff)
Merge branch 'user' into dev
-rw-r--r--Makefile.in32
-rw-r--r--lib/Makefile7
-rw-r--r--lib/libc/.gitignore1
-rw-r--r--lib/libc/Makefile28
-rw-r--r--lib/libc/include/bits/_types.h47
-rw-r--r--lib/libc/include/elf.h499
-rw-r--r--lib/libc/include/stddef.h45
-rw-r--r--lib/libc/include/stdint.h65
-rw-r--r--lib/libc/include/sys/auxv.h55
-rw-r--r--lib/libc/include/sys/syscall.h116
-rw-r--r--lib/libc/include/unistd.h44
-rw-r--r--lib/libc/linker/entry.S51
-rw-r--r--lib/libc/linker/entry.c60
-rw-r--r--lib/libc/src/exit.c37
-rw-r--r--share/man/man9/arch.918
-rw-r--r--share/man/man9/pmap.913
-rw-r--r--sys/arch/amd64/amd64/machdep.c82
-rw-r--r--sys/arch/amd64/amd64/pmap.c13
-rw-r--r--sys/arch/amd64/amd64/spectre.c7
-rw-r--r--sys/arch/amd64/amd64/syscall.S43
-rw-r--r--sys/arch/amd64/amd64/syscall.c49
-rw-r--r--sys/arch/amd64/amd64/trap.S10
-rw-r--r--sys/arch/amd64/amd64/trap.c12
-rw-r--r--sys/fs/initramfs.c9
-rw-r--r--sys/include/arch/amd64/cpu.h40
-rw-r--r--sys/include/arch/amd64/frame.h7
-rw-r--r--sys/include/arch/amd64/pcb.h39
-rw-r--r--sys/include/arch/amd64/trap.h2
-rw-r--r--sys/include/sys/filedesc.h53
-rw-r--r--sys/include/sys/loader.h27
-rw-r--r--sys/include/sys/machdep.h4
-rw-r--r--sys/include/sys/mount.h7
-rw-r--r--sys/include/sys/proc.h10
-rw-r--r--sys/include/sys/sched.h2
-rw-r--r--sys/include/sys/syscall.h56
-rw-r--r--sys/include/sys/vfs.h2
-rw-r--r--sys/include/sys/vnode.h1
-rw-r--r--sys/include/vm/pmap.h6
-rw-r--r--sys/include/vm/vm.h1
-rw-r--r--sys/kern/kern_filedesc.c123
-rw-r--r--sys/kern/kern_loader.c33
-rw-r--r--sys/kern/kern_sched.c275
-rw-r--r--sys/kern/kern_syscall.c44
-rw-r--r--sys/kern/vfs_init.c5
-rw-r--r--sys/kern/vfs_lookup.c61
-rw-r--r--sys/vm/vm_init.c9
-rw-r--r--sys/vm/vm_map.c6
-rw-r--r--tools/cross.sh2
-rw-r--r--usr.sbin/Makefile7
-rw-r--r--usr.sbin/init/Makefile8
-rw-r--r--usr.sbin/init/main.c6
51 files changed, 2080 insertions, 99 deletions
diff --git a/Makefile.in b/Makefile.in
index 8b098c6..f4336a7 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -47,6 +47,8 @@ else
override LD = $(shell pwd)/cross/bin/$(ARCH)-hyra-ld
endif
override AS = $(CC)
+override LDSO = $(shell pwd)/base/usr/lib/ld.so
+override USER_MKFLGS = CC=$(CC) LD=$(LD) LDSO=$(LDSO)
##########################
# Architecture specifics
@@ -69,10 +71,28 @@ override KERNEL_ASMOBJECTS = $(KERNEL_ASMFILES:.S=.S.o)
override KERNEL_HEADER_DEPS = $(KERNEL_CFILES:.c=.d)
.PHONY: all
-all: base/boot/hyra-kernel
+all: base lib userland base/usr/lib/ld.so base/boot/hyra-kernel
rm -f sys/include/machine
rm -rf iso_root
+base/usr/sbin/init:
+ cd usr.sbin/; make $(USER_MKFLGS)
+ mv usr.sbin/init/init base/usr/sbin/
+
+# TODO: Make this more flexible
+.PHONY: userland
+userland: base/usr/sbin/init
+
+base:
+ mkdir -p base/usr/lib/
+ mkdir -p base/usr/sbin/
+ mkdir -p base/boot/
+
+.PHONY: lib
+lib:
+ cd lib/; make $(USER_MKFLGS)
+ cp lib/libc/build/ld.so base/usr/lib/
+
.PHONY: run
run:
$(QEMU) $(QEMU_FLAGS)
@@ -82,6 +102,15 @@ cross:
bash tools/cross.sh $(ARCH)
.PHONY: clean
+distclean:
+ make clean
+ rm -f $(KERNEL_ASMOBJECTS) $(KERNEL_OBJECTS) $(KERNEL_HEADER_DEPS)
+ rm -f sys/include/machine
+ rm -f base/usr/lib/ld.so
+ rm -f base/boot/init
+ cd lib/; make clean
+
+.PHONY: clean
clean:
rm -f $(KERNEL_ASMOBJECTS) $(KERNEL_OBJECTS) $(KERNEL_HEADER_DEPS)
rm -f sys/include/machine
@@ -91,7 +120,6 @@ sys/include/machine/:
base/boot/hyra-kernel: $(KERNEL_OBJECTS) $(KERNEL_ASMOBJECTS)
rm -rf iso_root
- mkdir -p base/boot/
$(PROMPT) " LD " $(shell pwd)/base/boot/hyra-kernel
$(LD) $(KERNEL_LDFLAGS) $(KERNEL_OBJECTS) $(KERNEL_ASMOBJECTS) -o base/boot/hyra-kernel
tools/ksyms sys/kern/ksyms.c base/boot/hyra-kernel
diff --git a/lib/Makefile b/lib/Makefile
new file mode 100644
index 0000000..3881833
--- /dev/null
+++ b/lib/Makefile
@@ -0,0 +1,7 @@
+.PHONY: libc
+libc:
+ cd libc; make CC=$(CC)
+
+.PHONY: clean
+clean:
+ cd libc/; make clean
diff --git a/lib/libc/.gitignore b/lib/libc/.gitignore
new file mode 100644
index 0000000..567609b
--- /dev/null
+++ b/lib/libc/.gitignore
@@ -0,0 +1 @@
+build/
diff --git a/lib/libc/Makefile b/lib/libc/Makefile
new file mode 100644
index 0000000..aa09a4c
--- /dev/null
+++ b/lib/libc/Makefile
@@ -0,0 +1,28 @@
+CFLAGS = -c -fno-stack-protector -nostdlib -static -Iinclude/
+LIBC_CFILES = $(shell find src/ -name "*.c")
+LIBC_ASMFILES = $(shell find src/ -name "*.S")
+
+LIBC_OBJ = $(LIBC_CFILES:.c=.o)
+LIBC_ASMOBJ = $(LIBC_ASMFILES:.S=.S.o)
+
+all: $(LIBC_OBJ) build/ld.so
+
+build/ld.so: build/ linker/entry.c linker/entry.S
+ mkdir -p $(@D)
+ $(CC) $(CFLAGS) linker/entry.S -o build/entry.S.o
+ $(CC) $(CFLAGS) linker/entry.c -o build/entry.o
+ $(LD) build/entry.o build/entry.S.o -o $(LIBC_OBJ) -o $@
+
+%.o: %.c
+ $(CC) $(CFLAGS) $< -o $@
+
+%.S.o: %.S
+ gcc $(CFLAGS) $< -o $@
+
+.PHONY:
+build/:
+ mkdir -p build/
+
+.PHONY: clean
+clean:
+ rm -rf build/
diff --git a/lib/libc/include/bits/_types.h b/lib/libc/include/bits/_types.h
new file mode 100644
index 0000000..5f84e5e
--- /dev/null
+++ b/lib/libc/include/bits/_types.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _BITS__TYPES_H
+#define _BITS__TYPES_H
+
+typedef unsigned long __size_t;
+typedef long __ssize_t;
+typedef long __ptrdiff_t;
+
+typedef __UINT8_TYPE__ __uint8_t;
+typedef __UINT16_TYPE__ __uint16_t;
+typedef __UINT32_TYPE__ __uint32_t;
+typedef __UINT64_TYPE__ __uint64_t;
+
+typedef __INT8_TYPE__ __int8_t;
+typedef __INT16_TYPE__ __int16_t;
+typedef __INT32_TYPE__ __int32_t;
+typedef __INT64_TYPE__ __int64_t;
+
+#endif /* !_BITS__TYPES_H */
diff --git a/lib/libc/include/elf.h b/lib/libc/include/elf.h
new file mode 100644
index 0000000..4e0c1eb
--- /dev/null
+++ b/lib/libc/include/elf.h
@@ -0,0 +1,499 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_ELF_H_
+#define _SYS_ELF_H_
+
+#include <stdint.h>
+
+/* Type for a 16-bit quantity. */
+typedef uint16_t Elf32_Half;
+typedef uint16_t Elf64_Half;
+
+/* Types for signed and unsigned 32-bit quantities. */
+typedef uint32_t Elf32_Word;
+typedef int32_t Elf32_Sword;
+typedef uint32_t Elf64_Word;
+typedef int32_t Elf64_Sword;
+
+/* Types for signed and unsigned 64-bit quantities. */
+typedef uint64_t Elf32_Xword;
+typedef int64_t Elf32_Sxword;
+typedef uint64_t Elf64_Xword;
+typedef int64_t Elf64_Sxword;
+
+/* Type of addresses. */
+typedef uint32_t Elf32_Addr;
+typedef uint64_t Elf64_Addr;
+
+/* Type of file offsets. */
+typedef uint32_t Elf32_Off;
+typedef uint64_t Elf64_Off;
+
+/* Type for section indices, which are 16-bit quantities. */
+typedef uint16_t Elf32_Section;
+typedef uint16_t Elf64_Section;
+
+/* Type for version symbol information. */
+typedef Elf32_Half Elf32_Versym;
+typedef Elf64_Half Elf64_Versym;
+
+#define EI_MAG0 0 /* File identification byte 0 index */
+#define ELFMAG0 0x7f /* Magic number byte 0 */
+
+#define EI_MAG1 1 /* File identification byte 1 index */
+#define ELFMAG1 'E' /* Magic number byte 1 */
+
+#define EI_MAG2 2 /* File identification byte 2 index */
+#define ELFMAG2 'L' /* Magic number byte 2 */
+
+#define EI_MAG3 3 /* File identification byte 3 index */
+#define ELFMAG3 'F' /* Magic number byte 3 */
+
+/* Conglomeration of the identification bytes, for easy testing as a word. */
+#define ELFMAG "\177ELF"
+#define SELFMAG 4
+
+#define EI_CLASS 4 /* File class byte index */
+#define ELFCLASSNONE 0 /* Invalid class */
+#define ELFCLASS32 1 /* 32-bit objects */
+#define ELFCLASS64 2 /* 64-bit objects */
+#define ELFCLASSNUM 3
+
+#define EI_DATA 5 /* Data encoding byte index */
+#define ELFDATANONE 0 /* Invalid data encoding */
+#define ELFDATA2LSB 1 /* 2's complement, little endian */
+#define ELFDATA2MSB 2 /* 2's complement, big endian */
+#define ELFDATANUM 3
+
+#define EI_VERSION 6 /* File version byte index */
+ /* Value must be EV_CURRENT */
+
+#define EI_OSABI 7 /* OS ABI identification */
+#define ELFOSABI_NONE 0 /* UNIX System V ABI */
+#define ELFOSABI_SYSV 0 /* Alias. */
+#define ELFOSABI_HPUX 1 /* HP-UX */
+#define ELFOSABI_NETBSD 2 /* NetBSD. */
+#define ELFOSABI_GNU 3 /* Object uses GNU ELF extensions. */
+#define ELFOSABI_LINUX ELFOSABI_GNU /* Compatibility alias. */
+#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */
+#define ELFOSABI_AIX 7 /* IBM AIX. */
+#define ELFOSABI_IRIX 8 /* SGI Irix. */
+#define ELFOSABI_FREEBSD 9 /* FreeBSD. */
+#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */
+#define ELFOSABI_MODESTO 11 /* Novell Modesto. */
+#define ELFOSABI_OPENBSD 12 /* OpenBSD. */
+#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */
+#define ELFOSABI_ARM 97 /* ARM */
+#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
+
+#define EI_ABIVERSION 8 /* ABI version */
+
+#define EI_PAD 9 /* Byte index of padding bytes */
+
+/* Legal values for e_type (object file type). */
+
+#define ET_NONE 0 /* No file type */
+#define ET_REL 1 /* Relocatable file */
+#define ET_EXEC 2 /* Executable file */
+#define ET_DYN 3 /* Shared object file */
+#define ET_CORE 4 /* Core file */
+#define ET_NUM 5 /* Number of defined types */
+#define ET_LOOS 0xfe00 /* OS-specific range start */
+#define ET_HIOS 0xfeff /* OS-specific range end */
+#define ET_LOPROC 0xff00 /* Processor-specific range start */
+#define ET_HIPROC 0xffff /* Processor-specific range end */
+
+/* Legal values for e_machine (architecture). */
+
+#define EM_NONE 0 /* No machine */
+#define EM_M32 1 /* AT&T WE 32100 */
+#define EM_SPARC 2 /* SUN SPARC */
+#define EM_386 3 /* Intel 80386 */
+#define EM_68K 4 /* Motorola m68k family */
+#define EM_88K 5 /* Motorola m88k family */
+#define EM_IAMCU 6 /* Intel MCU */
+#define EM_860 7 /* Intel 80860 */
+#define EM_MIPS 8 /* MIPS R3000 big-endian */
+#define EM_S370 9 /* IBM System/370 */
+#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */
+ /* reserved 11-14 */
+#define EM_PARISC 15 /* HPPA */
+ /* reserved 16 */
+#define EM_VPP500 17 /* Fujitsu VPP500 */
+#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */
+#define EM_960 19 /* Intel 80960 */
+#define EM_PPC 20 /* PowerPC */
+#define EM_PPC64 21 /* PowerPC 64-bit */
+#define EM_S390 22 /* IBM S390 */
+#define EM_SPU 23 /* IBM SPU/SPC */
+ /* reserved 24-35 */
+#define EM_V800 36 /* NEC V800 series */
+#define EM_FR20 37 /* Fujitsu FR20 */
+#define EM_RH32 38 /* TRW RH-32 */
+#define EM_RCE 39 /* Motorola RCE */
+#define EM_ARM 40 /* ARM */
+#define EM_FAKE_ALPHA 41 /* Digital Alpha */
+#define EM_SH 42 /* Hitachi SH */
+#define EM_SPARCV9 43 /* SPARC v9 64-bit */
+#define EM_TRICORE 44 /* Siemens Tricore */
+#define EM_ARC 45 /* Argonaut RISC Core */
+#define EM_H8_300 46 /* Hitachi H8/300 */
+#define EM_H8_300H 47 /* Hitachi H8/300H */
+#define EM_H8S 48 /* Hitachi H8S */
+#define EM_H8_500 49 /* Hitachi H8/500 */
+#define EM_IA_64 50 /* Intel Merced */
+#define EM_MIPS_X 51 /* Stanford MIPS-X */
+#define EM_COLDFIRE 52 /* Motorola Coldfire */
+#define EM_68HC12 53 /* Motorola M68HC12 */
+#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator */
+#define EM_PCP 55 /* Siemens PCP */
+#define EM_NCPU 56 /* Sony nCPU embeeded RISC */
+#define EM_NDR1 57 /* Denso NDR1 microprocessor */
+#define EM_STARCORE 58 /* Motorola Start*Core processor */
+#define EM_ME16 59 /* Toyota ME16 processor */
+#define EM_ST100 60 /* STMicroelectronic ST100 processor */
+#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam */
+#define EM_X86_64 62 /* AMD x86-64 architecture */
+#define EM_PDSP 63 /* Sony DSP Processor */
+#define EM_PDP10 64 /* Digital PDP-10 */
+#define EM_PDP11 65 /* Digital PDP-11 */
+#define EM_FX66 66 /* Siemens FX66 microcontroller */
+#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */
+#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */
+#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */
+#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */
+#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */
+#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */
+#define EM_SVX 73 /* Silicon Graphics SVx */
+#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */
+#define EM_VAX 75 /* Digital VAX */
+#define EM_CRIS 76 /* Axis Communications 32-bit emb.proc */
+#define EM_JAVELIN 77 /* Infineon Technologies 32-bit emb.proc */
+#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */
+#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */
+#define EM_MMIX 80 /* Donald Knuth's educational 64-bit proc */
+#define EM_HUANY 81 /* Harvard University machine-independent object files */
+#define EM_PRISM 82 /* SiTera Prism */
+#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */
+#define EM_FR30 84 /* Fujitsu FR30 */
+#define EM_D10V 85 /* Mitsubishi D10V */
+#define EM_D30V 86 /* Mitsubishi D30V */
+#define EM_V850 87 /* NEC v850 */
+#define EM_M32R 88 /* Mitsubishi M32R */
+#define EM_MN10300 89 /* Matsushita MN10300 */
+#define EM_MN10200 90 /* Matsushita MN10200 */
+#define EM_PJ 91 /* picoJava */
+#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */
+#define EM_ARC_COMPACT 93 /* ARC International ARCompact */
+#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */
+#define EM_VIDEOCORE 95 /* Alphamosaic VideoCore */
+#define EM_TMM_GPP 96 /* Thompson Multimedia General Purpose Proc */
+#define EM_NS32K 97 /* National Semi. 32000 */
+#define EM_TPC 98 /* Tenor Network TPC */
+#define EM_SNP1K 99 /* Trebia SNP 1000 */
+#define EM_ST200 100 /* STMicroelectronics ST200 */
+#define EM_IP2K 101 /* Ubicom IP2xxx */
+#define EM_MAX 102 /* MAX processor */
+#define EM_CR 103 /* National Semi. CompactRISC */
+#define EM_F2MC16 104 /* Fujitsu F2MC16 */
+#define EM_MSP430 105 /* Texas Instruments msp430 */
+#define EM_BLACKFIN 106 /* Analog Devices Blackfin DSP */
+#define EM_SE_C33 107 /* Seiko Epson S1C33 family */
+#define EM_SEP 108 /* Sharp embedded microprocessor */
+#define EM_ARCA 109 /* Arca RISC */
+#define EM_UNICORE 110 /* PKU-Unity & MPRC Peking Uni. mc series */
+#define EM_EXCESS 111 /* eXcess configurable cpu */
+#define EM_DXP 112 /* Icera Semi. Deep Execution Processor */
+#define EM_ALTERA_NIOS2 113 /* Altera Nios II */
+#define EM_CRX 114 /* National Semi. CompactRISC CRX */
+#define EM_XGATE 115 /* Motorola XGATE */
+#define EM_C166 116 /* Infineon C16x/XC16x */
+#define EM_M16C 117 /* Renesas M16C */
+#define EM_DSPIC30F 118 /* Microchip Technology dsPIC30F */
+#define EM_CE 119 /* Freescale Communication Engine RISC */
+#define EM_M32C 120 /* Renesas M32C */
+ /* reserved 121-130 */
+#define EM_TSK3000 131 /* Altium TSK3000 */
+#define EM_RS08 132 /* Freescale RS08 */
+#define EM_SHARC 133 /* Analog Devices SHARC family */
+#define EM_ECOG2 134 /* Cyan Technology eCOG2 */
+#define EM_SCORE7 135 /* Sunplus S+core7 RISC */
+#define EM_DSP24 136 /* New Japan Radio (NJR) 24-bit DSP */
+#define EM_VIDEOCORE3 137 /* Broadcom VideoCore III */
+#define EM_LATTICEMICO32 138 /* RISC for Lattice FPGA */
+#define EM_SE_C17 139 /* Seiko Epson C17 */
+#define EM_TI_C6000 140 /* Texas Instruments TMS320C6000 DSP */
+#define EM_TI_C2000 141 /* Texas Instruments TMS320C2000 DSP */
+#define EM_TI_C5500 142 /* Texas Instruments TMS320C55x DSP */
+#define EM_TI_ARP32 143 /* Texas Instruments App. Specific RISC */
+#define EM_TI_PRU 144 /* Texas Instruments Prog. Realtime Unit */
+ /* reserved 145-159 */
+#define EM_MMDSP_PLUS 160 /* STMicroelectronics 64bit VLIW DSP */
+#define EM_CYPRESS_M8C 161 /* Cypress M8C */
+#define EM_R32C 162 /* Renesas R32C */
+#define EM_TRIMEDIA 163 /* NXP Semi. TriMedia */
+#define EM_QDSP6 164 /* QUALCOMM DSP6 */
+#define EM_8051 165 /* Intel 8051 and variants */
+#define EM_STXP7X 166 /* STMicroelectronics STxP7x */
+#define EM_NDS32 167 /* Andes Tech. compact code emb. RISC */
+#define EM_ECOG1X 168 /* Cyan Technology eCOG1X */
+#define EM_MAXQ30 169 /* Dallas Semi. MAXQ30 mc */
+#define EM_XIMO16 170 /* New Japan Radio (NJR) 16-bit DSP */
+#define EM_MANIK 171 /* M2000 Reconfigurable RISC */
+#define EM_CRAYNV2 172 /* Cray NV2 vector architecture */
+#define EM_RX 173 /* Renesas RX */
+#define EM_METAG 174 /* Imagination Tech. META */
+#define EM_MCST_ELBRUS 175 /* MCST Elbrus */
+#define EM_ECOG16 176 /* Cyan Technology eCOG16 */
+#define EM_CR16 177 /* National Semi. CompactRISC CR16 */
+#define EM_ETPU 178 /* Freescale Extended Time Processing Unit */
+#define EM_SLE9X 179 /* Infineon Tech. SLE9X */
+#define EM_L10M 180 /* Intel L10M */
+#define EM_K10M 181 /* Intel K10M */
+ /* reserved 182 */
+#define EM_AARCH64 183 /* ARM AARCH64 */
+ /* reserved 184 */
+#define EM_AVR32 185 /* Amtel 32-bit microprocessor */
+#define EM_STM8 186 /* STMicroelectronics STM8 */
+#define EM_TILE64 187 /* Tileta TILE64 */
+#define EM_TILEPRO 188 /* Tilera TILEPro */
+#define EM_MICROBLAZE 189 /* Xilinx MicroBlaze */
+#define EM_CUDA 190 /* NVIDIA CUDA */
+#define EM_TILEGX 191 /* Tilera TILE-Gx */
+#define EM_CLOUDSHIELD 192 /* CloudShield */
+#define EM_COREA_1ST 193 /* KIPO-KAIST Core-A 1st gen. */
+#define EM_COREA_2ND 194 /* KIPO-KAIST Core-A 2nd gen. */
+#define EM_ARC_COMPACT2 195 /* Synopsys ARCompact V2 */
+#define EM_OPEN8 196 /* Open8 RISC */
+#define EM_RL78 197 /* Renesas RL78 */
+#define EM_VIDEOCORE5 198 /* Broadcom VideoCore V */
+#define EM_78KOR 199 /* Renesas 78KOR */
+#define EM_56800EX 200 /* Freescale 56800EX DSC */
+#define EM_BA1 201 /* Beyond BA1 */
+#define EM_BA2 202 /* Beyond BA2 */
+#define EM_XCORE 203 /* XMOS xCORE */
+#define EM_MCHP_PIC 204 /* Microchip 8-bit PIC(r) */
+ /* reserved 205-209 */
+#define EM_KM32 210 /* KM211 KM32 */
+#define EM_KMX32 211 /* KM211 KMX32 */
+#define EM_EMX16 212 /* KM211 KMX16 */
+#define EM_EMX8 213 /* KM211 KMX8 */
+#define EM_KVARC 214 /* KM211 KVARC */
+#define EM_CDP 215 /* Paneve CDP */
+#define EM_COGE 216 /* Cognitive Smart Memory Processor */
+#define EM_COOL 217 /* Bluechip CoolEngine */
+#define EM_NORC 218 /* Nanoradio Optimized RISC */
+#define EM_CSR_KALIMBA 219 /* CSR Kalimba */
+#define EM_Z80 220 /* Zilog Z80 */
+#define EM_VISIUM 221 /* Controls and Data Services VISIUMcore */
+#define EM_FT32 222 /* FTDI Chip FT32 */
+#define EM_MOXIE 223 /* Moxie processor */
+#define EM_AMDGPU 224 /* AMD GPU */
+ /* reserved 225-242 */
+#define EM_RISCV 243 /* RISC-V */
+
+#define EM_BPF 247 /* Linux BPF -- in-kernel virtual machine */
+
+#define EM_NUM 248
+
+/* Old spellings/synonyms. */
+
+#define EM_ARC_A5 EM_ARC_COMPACT
+
+/* If it is necessary to assign new unofficial EM_* values, please
+ pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
+ chances of collision with official or non-GNU unofficial values. */
+
+#define EM_ALPHA 0x9026
+
+/* Legal values for e_version (version). */
+
+#define EV_NONE 0 /* Invalid ELF version */
+#define EV_CURRENT 1 /* Current version */
+#define EV_NUM 2
+
+#define EI_NIDENT (16)
+
+#define PT_NULL 0 /* Program header table entry unused */
+#define PT_LOAD 1 /* Loadable program segment */
+#define PT_DYNAMIC 2 /* Dynamic linking information */
+#define PT_INTERP 3 /* Program interpreter */
+#define PT_NOTE 4 /* Auxiliary information */
+#define PT_SHLIB 5 /* Reserved */
+#define PT_PHDR 6 /* Entry for header table itself */
+#define PT_TLS 7 /* Thread-local storage segment */
+#define PT_NUM 8 /* Number of defined types */
+#define PT_LOOS 0x60000000 /* Start of OS-specific */
+#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */
+#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */
+#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */
+#define PT_LOSUNW 0x6ffffffa
+#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */
+#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */
+#define PT_HISUNW 0x6fffffff
+#define PT_HIOS 0x6fffffff /* End of OS-specific */
+#define PT_LOPROC 0x70000000 /* Start of processor-specific */
+#define PT_HIPROC 0x7fffffff /* End of processor-specific */
+
+/* Legal values for p_flags (segment flags). */
+
+#define PF_X (1 << 0) /* Segment is executable */
+#define PF_W (1 << 1) /* Segment is writable */
+#define PF_R (1 << 2) /* Segment is readable */
+#define PF_MASKOS 0x0ff00000 /* OS-specific */
+#define PF_MASKPROC 0xf0000000 /* Processor-specific */
+
+/* Legal values for note segment descriptor types for core files. */
+
+#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */
+#define NT_PRFPREG 2 /* Contains copy of fpregset
+ struct. */
+#define NT_FPREGSET 2 /* Contains copy of fpregset struct */
+#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */
+#define NT_PRXREG 4 /* Contains copy of prxregset struct */
+#define NT_TASKSTRUCT 4 /* Contains copy of task structure */
+#define NT_PLATFORM 5 /* String from sysinfo(SI_PLATFORM) */
+#define NT_AUXV 6 /* Contains copy of auxv array */
+#define NT_GWINDOWS 7 /* Contains copy of gwindows struct */
+#define NT_ASRS 8 /* Contains copy of asrset struct */
+#define NT_PSTATUS 10 /* Contains copy of pstatus struct */
+#define NT_PSINFO 13 /* Contains copy of psinfo struct */
+#define NT_PRCRED 14 /* Contains copy of prcred struct */
+#define NT_UTSNAME 15 /* Contains copy of utsname struct */
+#define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */
+#define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */
+#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct */
+#define NT_SIGINFO 0x53494749 /* Contains copy of siginfo_t,
+ size might increase */
+#define NT_FILE 0x46494c45 /* Contains information about mapped
+ files */
+#define NT_PRXFPREG 0x46e62b7f /* Contains copy of user_fxsr_struct */
+#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */
+#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */
+#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */
+#define NT_PPC_TAR 0x103 /* Target Address Register */
+#define NT_PPC_PPR 0x104 /* Program Priority Register */
+#define NT_PPC_DSCR 0x105 /* Data Stream Control Register */
+#define NT_PPC_EBB 0x106 /* Event Based Branch Registers */
+#define NT_PPC_PMU 0x107 /* Performance Monitor Registers */
+#define NT_PPC_TM_CGPR 0x108 /* TM checkpointed GPR Registers */
+#define NT_PPC_TM_CFPR 0x109 /* TM checkpointed FPR Registers */
+#define NT_PPC_TM_CVMX 0x10a /* TM checkpointed VMX Registers */
+#define NT_PPC_TM_CVSX 0x10b /* TM checkpointed VSX Registers */
+#define NT_PPC_TM_SPR 0x10c /* TM Special Purpose Registers */
+#define NT_PPC_TM_CTAR 0x10d /* TM checkpointed Target Address
+ Register */
+#define NT_PPC_TM_CPPR 0x10e /* TM checkpointed Program Priority
+ Register */
+#define NT_PPC_TM_CDSCR 0x10f /* TM checkpointed Data Stream Control
+ Register */
+#define NT_PPC_PKEY 0x110 /* Memory Protection Keys
+ registers. */
+#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */
+#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */
+#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */
+#define NT_S390_HIGH_GPRS 0x300 /* s390 upper register halves */
+#define NT_S390_TIMER 0x301 /* s390 timer register */
+#define NT_S390_TODCMP 0x302 /* s390 TOD clock comparator register */
+#define NT_S390_TODPREG 0x303 /* s390 TOD programmable register */
+#define NT_S390_CTRS 0x304 /* s390 control registers */
+#define NT_S390_PREFIX 0x305 /* s390 prefix register */
+#define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */
+#define NT_S390_SYSTEM_CALL 0x307 /* s390 system call restart data */
+#define NT_S390_TDB 0x308 /* s390 transaction diagnostic block */
+#define NT_S390_VXRS_LOW 0x309 /* s390 vector registers 0-15
+ upper half. */
+#define NT_S390_VXRS_HIGH 0x30a /* s390 vector registers 16-31. */
+#define NT_S390_GS_CB 0x30b /* s390 guarded storage registers. */
+#define NT_S390_GS_BC 0x30c /* s390 guarded storage
+ broadcast control block. */
+#define NT_S390_RI_CB 0x30d /* s390 runtime instrumentation. */
+#define NT_ARM_VFP 0x400 /* ARM VFP/NEON registers */
+#define NT_ARM_TLS 0x401 /* ARM TLS register */
+#define NT_ARM_HW_BREAK 0x402 /* ARM hardware breakpoint registers */
+#define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */
+#define NT_ARM_SYSTEM_CALL 0x404 /* ARM system call number */
+#define NT_ARM_SVE 0x405 /* ARM Scalable Vector Extension
+ registers */
+#define NT_VMCOREDD 0x700 /* Vmcore Device Dump Note. */
+
+/* Legal values for the note segment descriptor types for object files. */
+
+#define NT_VERSION 1 /* Contains a version string. */
+
+typedef struct
+{
+ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
+ Elf64_Half e_type; /* Object file type */
+ Elf64_Half e_machine; /* Architecture */
+ Elf64_Word e_version; /* Object file version */
+ Elf64_Addr e_entry; /* Entry point virtual address */
+ Elf64_Off e_phoff; /* Program header table file offset */
+ Elf64_Off e_shoff; /* Section header table file offset */
+ Elf64_Word e_flags; /* Processor-specific flags */
+ Elf64_Half e_ehsize; /* ELF header size in bytes */
+ Elf64_Half e_phentsize; /* Program header table entry size */
+ Elf64_Half e_phnum; /* Program header table entry count */
+ Elf64_Half e_shentsize; /* Section header table entry size */
+ Elf64_Half e_shnum; /* Section header table entry count */
+ Elf64_Half e_shstrndx; /* Section header string table index */
+} Elf64_Ehdr;
+
+typedef struct
+{
+ Elf64_Word p_type; /* Segment type */
+ Elf64_Word p_flags; /* Segment flags */
+ Elf64_Off p_offset; /* Segment file offset */
+ Elf64_Addr p_vaddr; /* Segment virtual address */
+ Elf64_Addr p_paddr; /* Segment physical address */
+ Elf64_Xword p_filesz; /* Segment size in file */
+ Elf64_Xword p_memsz; /* Segment size in memory */
+ Elf64_Xword p_align; /* Segment alignment */
+} Elf64_Phdr;
+
+typedef struct {
+ Elf64_Addr r_offset; /* Location at which to apply the action */
+ Elf64_Xword r_info; /* index and type of relocation */
+} Elf64_Rel;
+
+typedef struct {
+ Elf64_Word sh_name; /* Section name, index in string tbl */
+ Elf64_Word sh_type; /* Type of section */
+ Elf64_Xword sh_flags; /* Miscellaneous section attributes */
+ Elf64_Addr sh_addr; /* Section virtual addr at execution */
+ Elf64_Off sh_offset; /* Section file offset */
+ Elf64_Xword sh_size; /* Size of section in bytes */
+ Elf64_Word sh_link; /* Index of another section */
+ Elf64_Word sh_info; /* Additional section information */
+ Elf64_Xword sh_addralign; /* Section alignment */
+ Elf64_Xword sh_entsize; /* Entry size if section holds table */
+} Elf64_Shdr;
+
+#endif /* _SYS_ELF_H_ */
diff --git a/lib/libc/include/stddef.h b/lib/libc/include/stddef.h
new file mode 100644
index 0000000..70b3ccf
--- /dev/null
+++ b/lib/libc/include/stddef.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _STDDEF_H
+#define _STDDEF_H
+
+#include <bits/_types.h>
+
+#if __cplusplus >= 201103L
+#define NULL nullptr
+#elif defined(__cplusplus)
+#define NULL 0L
+#else
+#define NULL ((void *) 0)
+#endif
+
+typedef __size_t size_t;
+
+#endif /* !_STDDEF_H */
diff --git a/lib/libc/include/stdint.h b/lib/libc/include/stdint.h
new file mode 100644
index 0000000..ed6aa08
--- /dev/null
+++ b/lib/libc/include/stdint.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _STDINT_H
+#define _STDINT_H
+
+#include <bits/_types.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+typedef __uint8_t uint8_t;
+typedef __uint16_t uint16_t;
+typedef __uint32_t uint32_t;
+typedef __uint64_t uint64_t;
+
+typedef __int8_t int8_t;
+typedef __int16_t int16_t;
+typedef __int32_t int32_t;
+typedef __int64_t int64_t;
+
+/* Signed fixed-width limits */
+#define INT8_MAX __INT8_MAX
+#define INT16_MAX __INT16_MAX
+#define INT32_MAX __INT32_MAX
+#define INT64_MAX __INT64_MAX
+
+/* Unsigned fixed-width limits */
+#define UINT8_MAX __UINT8_MAX
+#define UINT16_MAX __UINT16_MAX
+#define UINT32_MAX __UINT32_MAX
+#define UINT64_MAX __UINT64_MAX
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_STDINT_H */
diff --git a/lib/libc/include/sys/auxv.h b/lib/libc/include/sys/auxv.h
new file mode 100644
index 0000000..b06d01c
--- /dev/null
+++ b/lib/libc/include/sys/auxv.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_AUXV_H
+#define _SYS_AUXV_H
+
+#include <stdint.h>
+
+#define AT_NULL 0
+#define AT_ENTRY 1
+#define AT_PHDR 2
+#define AT_PHENT 3
+#define AT_PHNUM 4
+#define AT_EXECPATH 5
+#define AT_SECURE 6
+#define AT_RANDOM 7
+#define AT_EXECFN 8
+
+#define AT_MAX_COUNT 9
+
+struct auxv_entry {
+ uint64_t tag;
+ union {
+ uint64_t val;
+ void* ptr;
+ };
+};
+
+#endif /* _SYS_AUXV_H */
diff --git a/lib/libc/include/sys/syscall.h b/lib/libc/include/sys/syscall.h
new file mode 100644
index 0000000..34f762d
--- /dev/null
+++ b/lib/libc/include/sys/syscall.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_SYSCALL_H
+#define _SYS_SYSCALL_H
+
+#if !defined(__ASSEMBLER__)
+#include <stdint.h>
+#endif
+
+#define SYS_exit 1
+
+#if !defined(__ASSEMBLER__)
+__attribute__((__always_inline__))
+static inline long
+syscall0(uint64_t code)
+{
+ volatile long ret;
+ asm volatile("int $0x80" : "=a"(ret) : "a"(code));
+ return ret;
+}
+
+__attribute__((__always_inline__))
+static inline long
+syscall1(uint64_t code, uint64_t arg0)
+{
+ volatile long ret;
+ asm volatile("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0) : "memory");
+ return ret;
+}
+
+__attribute__((__always_inline__))
+static long inline
+syscall2(uint64_t code, uint64_t arg0, uint64_t arg1)
+{
+ volatile long ret;
+ asm volatile("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1) : "memory");
+ return ret;
+}
+
+__attribute__((__always_inline__))
+static inline long
+syscall3(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2)
+{
+ volatile long ret;
+ asm volatile("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1), "d"(arg2) : "memory");
+ return ret;
+}
+
+__attribute__((__always_inline__))
+static inline long
+syscall4(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3)
+{
+ volatile long ret;
+ register uint64_t _arg3 asm("r10") = arg3;
+ asm volatile("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1), "d"(arg2), "r"(_arg3) : "memory");
+ return ret;
+}
+
+__attribute__((__always_inline__))
+static inline long
+syscall5(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4)
+{
+ volatile long ret;
+ register uint64_t _arg3 asm("r10") = arg3;
+ register uint64_t _arg4 asm("r9") = arg4;
+ asm volatile("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1), "d"(arg2), "r"(_arg3), "r"(_arg4) : "memory");
+ return ret;
+}
+
+__attribute__((__always_inline__))
+static inline long
+syscall6(uint64_t code, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5) {
+ volatile long ret;
+ register uint64_t _arg3 asm("r10") = arg3;
+ register uint64_t _arg4 asm("r9") = arg4;
+ register uint64_t _arg5 asm("r8") = arg5;
+ asm volatile("int $0x80" : "=a"(ret) : "a"(code), "D"(arg0), "S"(arg1), "d"(arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5) : "memory");
+ return ret;
+}
+
+#define _SYSCALL_N(a0, a1, a2, a3, a4, a5, a6, name, ...) \
+ name
+
+#define syscall(...) \
+_SYSCALL_N(__VA_ARGS__, syscall6, syscall5, \
+ syscall4, syscall3, syscall2, syscall1, \
+ syscall0)(__VA_ARGS__)
+#endif /* !defined(__ASSEMBLER__) */
+#endif /* !_SYS_SYSCALL_H */
diff --git a/lib/libc/include/unistd.h b/lib/libc/include/unistd.h
new file mode 100644
index 0000000..47cde66
--- /dev/null
+++ b/lib/libc/include/unistd.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _UNISTD_H
+#define _UNISTD_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+_Noreturn void _exit(int status);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_UNISTD_H */
+
diff --git a/lib/libc/linker/entry.S b/lib/libc/linker/entry.S
new file mode 100644
index 0000000..1f982f9
--- /dev/null
+++ b/lib/libc/linker/entry.S
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if !defined(__hyra__)
+#error "Hyra supported only"
+#endif
+
+#include <sys/syscall.h>
+
+.section .text, "ax", @progbits
+.globl _start
+_start:
+ // Mark end of callstack
+ xor %rbp, %rbp
+
+ // Load process context as per the sysv AMD64 ABI
+ lea (%rsp), %rdi
+ call entry
+
+ // We are done, now we exit
+ mov $SYS_exit, %rax
+ xor %rdi, %rdi
+ int $0x80
+ nop
+ ud2
diff --git a/lib/libc/linker/entry.c b/lib/libc/linker/entry.c
new file mode 100644
index 0000000..55bf312
--- /dev/null
+++ b/lib/libc/linker/entry.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/syscall.h>
+#include <sys/auxv.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <elf.h>
+
+#if !defined(__hyra__)
+#error "Hyra supported only"
+#endif
+
+void
+entry(const uint64_t *ctx)
+{
+ uint64_t argc = *ctx;
+ uint64_t auxv[AT_MAX_COUNT] = {0};
+ int envc;
+
+ const char **argv = (const char **)(ctx + 1);
+ const char **envp = (const char **)(argv + argc + 1);
+ struct auxv_entry *auxvp;
+
+ /* Read-in auxiliary vector */
+ auxvp = (struct auxv_entry *)(envp + envc + 1);
+ for (; auxvp->tag != AT_NULL; ++auxvp) {
+ if (auxvp->tag < AT_MAX_COUNT) {
+ auxv[auxvp->tag] = auxvp->val;
+ }
+ }
+
+ /* TODO */
+}
diff --git a/lib/libc/src/exit.c b/lib/libc/src/exit.c
new file mode 100644
index 0000000..3b35ec6
--- /dev/null
+++ b/lib/libc/src/exit.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/syscall.h>
+
+_Noreturn void
+_exit(int status)
+{
+ syscall(SYS_exit, status);
+ __builtin_unreachable();
+}
diff --git a/share/man/man9/arch.9 b/share/man/man9/arch.9
index adbc437..5bcac2d 100644
--- a/share/man/man9/arch.9
+++ b/share/man/man9/arch.9
@@ -24,7 +24,7 @@
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
-.Dd Jan 12 2024
+.Dd Mar 13 2024
.Dt ARCH 9
.Os Hyra
.Sh NAME
@@ -113,5 +113,21 @@ header, should be a struct containing information
about the address space. This header MUST be implemented
or compiler errors will occur.
+There also exists a
+.Ft pcb
+(Process Control Block) structure in the
+.Ft machine/pcb.h
+header which contains arch specific information per thread.
+
+This structure must be implemented per arch, this structure shall be set up
+by the machdep subsystem, specifically in the
+.Ft processor_init_pcb()
+routine.
+
+The
+.Ft processor_free_pcb()
+routine shall also be implemented per arch to deallocate
+resources when the thread is killed.
+
.Sh AUTHORS
.An Ian Moffett Aq Mt ian@osmora.org
diff --git a/share/man/man9/pmap.9 b/share/man/man9/pmap.9
index 9e4d5e0..e50a8ab 100644
--- a/share/man/man9/pmap.9
+++ b/share/man/man9/pmap.9
@@ -24,7 +24,7 @@
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
-.Dd Jan 12 2024
+.Dd Mar 13 2024
.Dt PMAP 9
.Os Hyra
.Sh NAME
@@ -32,8 +32,11 @@
.Sh SYNOPSIS
.In vm/pmap.h
-.Ft pmap_map(struct vm_ctx *, vaddr_t, paddr_t, vm_prot_t);
-.Ft pmap_unmap(struct vm_ctx *, vaddr_t);
+.Bd -literal
+int pmap_map(struct vm_ctx *, vaddr_t, paddr_t, vm_prot_t);
+int pmap_unmap(struct vm_ctx *, vaddr_t);
+.Ed
+
.Sh DESCRIPTION
The machine dependent virtual memory layer contains a standard set of
functions that shall be implemented per architecture and left alone
@@ -48,13 +51,13 @@ vm_prot_t is used to give a mapping certain access
rules. These rules are described below:
The
-.Ft PMAP_WRITABLE
+.Ft PROT_WRITABLE
bit tells pmap_map() to allow writes to the page.
Writes to pages without this bit will result in an exception,
on AMD64 a #PF will occur.
The
-.Ft PMAP_EXEC
+.Ft PROT_EXEC
bit tells pmap_map() to allow this page to be
executable. On platforms like AMD64, execution of pages
without this bit will result in an exception from the
diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c
index 6342aab..47d6dd0 100644
--- a/sys/arch/amd64/amd64/machdep.c
+++ b/sys/arch/amd64/amd64/machdep.c
@@ -40,6 +40,7 @@
#include <machine/spectre.h>
#include <machine/cpu.h>
#include <machine/uart.h>
+#include <machine/cpuid.h>
#include <vm/vm.h>
#include <vm/dynalloc.h>
#include <vm/physseg.h>
@@ -56,6 +57,8 @@ __KERNEL_META("$Hyra$: machdep.c, Ian Marco Moffett, "
#define INIT_FLAG_IOAPIC 0x00000001U
#define INIT_FLAG_ACPI 0x00000002U
+void syscall_isr(void);
+
static inline void
init_tss(struct cpu_info *cur_cpu)
{
@@ -78,18 +81,28 @@ interrupts_init(void)
idt_set_desc(0x8, IDT_TRAP_GATE_FLAGS, ISR(double_fault), 0);
idt_set_desc(0xA, IDT_TRAP_GATE_FLAGS, ISR(invl_tss), 0);
idt_set_desc(0xB, IDT_TRAP_GATE_FLAGS, ISR(segnp), 0);
+ idt_set_desc(0xC, IDT_TRAP_GATE_FLAGS, ISR(ss_fault), 0);
idt_set_desc(0xD, IDT_TRAP_GATE_FLAGS, ISR(general_prot), 0);
idt_set_desc(0xE, IDT_TRAP_GATE_FLAGS, ISR(page_fault), 0);
+ idt_set_desc(0x80, IDT_INT_GATE_USER, ISR(syscall_isr), 0);
idt_load();
}
+static bool
+is_sse_supported(void)
+{
+ uint32_t edx, unused;
+
+ __CPUID(0x00000001, unused, unused, unused, edx);
+ return __TEST(edx, __BIT(25)) && __TEST(edx, __BIT(26));
+}
+
void
processor_halt(void)
{
__ASMV("cli; hlt");
}
-
/*
* Send char to serial for debugging purposes.
*/
@@ -144,11 +157,63 @@ intr_unmask(void)
__ASMV("sti");
}
+int
+processor_init_pcb(struct proc *proc)
+{
+ struct pcb *pcb = &proc->pcb;
+ const uint16_t FPU_FCW = 0x33F;
+ const uint32_t SSE_MXCSR = 0x1F80;
+
+ /* Allocate FPU save area, aligned on a 16 byte boundary */
+ pcb->fpu_state = PHYS_TO_VIRT(vm_alloc_pageframe(1));
+ if (pcb->fpu_state == NULL) {
+ return -1;
+ }
+
+ /*
+ * Setup x87 FPU control word and SSE MXCSR bits
+ * as per the sysv ABI
+ */
+ __ASMV("fldcw %0\n"
+ "ldmxcsr %1"
+ :: "m" (FPU_FCW),
+ "m" (SSE_MXCSR) : "memory");
+
+ amd64_fxsave(pcb->fpu_state);
+ return 0;
+}
+
+int
+processor_free_pcb(struct proc *proc)
+{
+ struct pcb *pcb = &proc->pcb;
+
+ if (pcb->fpu_state == NULL) {
+ return -1;
+ }
+
+ vm_free_pageframe(VIRT_TO_PHYS(pcb->fpu_state), 1);
+ return 0;
+}
+
+void
+processor_switch_to(struct proc *old_td, struct proc *new_td)
+{
+ struct pcb *old_pcb = (old_td != NULL) ? &old_td->pcb : NULL;
+ struct pcb *new_pcb = &new_td->pcb;
+
+ if (old_pcb != NULL) {
+ amd64_fxsave(old_pcb->fpu_state);
+ }
+ amd64_fxrstor(new_pcb->fpu_state);
+}
+
void
processor_init(void)
{
/* Indicates what doesn't need to be init anymore */
static uint8_t init_flags = 0;
+ static uint64_t reg_tmp;
struct cpu_info *cur_cpu;
/* Create our cpu_info structure */
@@ -159,6 +224,21 @@ processor_init(void)
/* Set %GS to cpu_info */
amd64_write_gs_base((uintptr_t)cur_cpu);
+ if (is_sse_supported()) {
+ /* Enable SSE/SSE2 */
+ reg_tmp = amd64_read_cr0();
+ reg_tmp &= ~(__BIT(2));
+ reg_tmp |= __BIT(1);
+ amd64_write_cr0(reg_tmp);
+
+ /* Enable FXSAVE/FXRSTOR */
+ reg_tmp = amd64_read_cr4();
+ reg_tmp |= 3 << 9;
+ amd64_write_cr4(reg_tmp);
+ } else {
+ panic("SSE/SSE2 not supported!\n");
+ }
+
CPU_INFO_LOCK(cur_cpu);
init_tss(cur_cpu);
diff --git a/sys/arch/amd64/amd64/pmap.c b/sys/arch/amd64/amd64/pmap.c
index 2760532..54d4ca3 100644
--- a/sys/arch/amd64/amd64/pmap.c
+++ b/sys/arch/amd64/amd64/pmap.c
@@ -228,6 +228,19 @@ pmap_switch_vas(struct vm_ctx *ctx, struct vas vas)
: "memory");
}
+/*
+ * TODO: During the mapping of a virtual address, a level
+ * may be allocated. This function does not handle the
+ * freeing of allocated levels. We should keep track
+ * of levels allocated and free them here.
+ */
+int
+pmap_free_vas(struct vm_ctx *ctx, struct vas vas)
+{
+ vm_free_pageframe(vas.top_level, 1);
+ return 0;
+}
+
struct vas
pmap_read_vas(void)
{
diff --git a/sys/arch/amd64/amd64/spectre.c b/sys/arch/amd64/amd64/spectre.c
index 1247607..05aa557 100644
--- a/sys/arch/amd64/amd64/spectre.c
+++ b/sys/arch/amd64/amd64/spectre.c
@@ -62,13 +62,18 @@ __weak int
try_spectre_mitigate(void)
{
uint64_t tmp;
+ static bool should_log = true;
if (!__can_mitigate_spectre()) {
KINFO("IBRS not supported; spectre mitigation NOT enabled\n");
return EXIT_FAILURE;
}
- KINFO("IBRS supported; spectre mitigation enabled\n");
+ /* This is called per processor, only log once */
+ if (should_log) {
+ KINFO("IBRS supported; spectre mitigation enabled\n");
+ should_log = false;
+ }
tmp = rdmsr(IA32_SPEC_CTL);
tmp |= __BIT(0); /* IBRS */
diff --git a/sys/arch/amd64/amd64/syscall.S b/sys/arch/amd64/amd64/syscall.S
new file mode 100644
index 0000000..fe70523
--- /dev/null
+++ b/sys/arch/amd64/amd64/syscall.S
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+ #include <sys/cdefs.h>
+ #include <machine/frameasm.h>
+
+__KERNEL_META "$Hyra$: syscall.S, Ian Marco Moffett, \
+ Syscall ISR code"
+
+.text
+.globl syscall_isr
+syscall_isr:
+ push_trapframe $0
+ mov %rsp, %rdi
+ call __syscall
+ pop_trapframe
+ iretq
diff --git a/sys/arch/amd64/amd64/syscall.c b/sys/arch/amd64/amd64/syscall.c
new file mode 100644
index 0000000..68235d5
--- /dev/null
+++ b/sys/arch/amd64/amd64/syscall.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/syscall.h>
+
+void
+__syscall(struct trapframe *tf)
+{
+ struct syscall_args args = {
+ .code = tf->rax,
+ .arg0 = tf->rdi,
+ .arg1 = tf->rsi,
+ .arg2 = tf->rcx,
+ .arg3 = tf->r8,
+ .arg4 = tf->r9,
+ .sp = tf->rsp
+ };
+
+ if (args.code < __MAX_SYSCALLS && args.code > 0) {
+ args.code -= 1;
+ tf->rax = g_syscall_table[args.code](&args);
+ }
+}
diff --git a/sys/arch/amd64/amd64/trap.S b/sys/arch/amd64/amd64/trap.S
index 5a77955..66dd2a9 100644
--- a/sys/arch/amd64/amd64/trap.S
+++ b/sys/arch/amd64/amd64/trap.S
@@ -144,3 +144,13 @@ nmi:
/* TODO */
cli
hlt
+
+.globl ss_fault
+ss_fault:
+ push_trapframe_ec $TRAP_SS
+
+ handle_trap
+
+ /* TODO */
+ cli
+ hlt
diff --git a/sys/arch/amd64/amd64/trap.c b/sys/arch/amd64/amd64/trap.c
index b73048d..f1e58f1 100644
--- a/sys/arch/amd64/amd64/trap.c
+++ b/sys/arch/amd64/amd64/trap.c
@@ -44,7 +44,8 @@ static const char *trap_type[] = {
[TRAP_SEGNP] = "segment not present",
[TRAP_PROTFLT] = "general protection",
[TRAP_PAGEFLT] = "page fault",
- [TRAP_NMI] = "non-maskable interrupt"
+ [TRAP_NMI] = "non-maskable interrupt",
+ [TRAP_SS] = "stack-segment fault"
};
static const int TRAP_COUNT = __ARRAY_COUNT(trap_type);
@@ -54,12 +55,17 @@ dbg_errcode(struct trapframe *tf)
{
uint64_t ec = tf->error_code;
- if (tf->trapno == TRAP_PAGEFLT) {
+ switch (tf->trapno) {
+ case TRAP_PAGEFLT:
kprintf("bits (pwui): %c%c%c%c\n",
__TEST(ec, __BIT(0)) ? 'p' : '-',
__TEST(ec, __BIT(1)) ? 'w' : '-',
__TEST(ec, __BIT(2)) ? 'u' : '-',
__TEST(ec, __BIT(4)) ? 'i' : '-');
+ break;
+ case TRAP_SS:
+ kprintf("ss: 0x%x\n", ec);
+ break;
}
}
@@ -115,5 +121,5 @@ trap_handler(struct trapframe *tf)
}
regdump(tf);
- panic("Caught pre-sched exception\n");
+ panic("Halted\n");
}
diff --git a/sys/fs/initramfs.c b/sys/fs/initramfs.c
index c0eaa0c..6da0929 100644
--- a/sys/fs/initramfs.c
+++ b/sys/fs/initramfs.c
@@ -103,7 +103,7 @@ vop_vget(struct vnode *parent, const char *name, struct vnode **vp)
return -ENOENT;
}
- if (hdr->type != TAR_TYPEFLAG_DIR) {
+ if (hdr->type == TAR_TYPEFLAG_DIR) {
vtype = VDIR;
}
@@ -149,8 +149,8 @@ static char *
get_module(const char *path, uint64_t *size) {
for (uint64_t i = 0; i < mod_req.response->module_count; ++i) {
if (strcmp(mod_req.response->modules[i]->path, path) == 0) {
- *size = mod_req.response->modules[i]->size;
- return mod_req.response->modules[i]->address;
+ *size = mod_req.response->modules[i]->size;
+ return mod_req.response->modules[i]->address;
}
}
@@ -173,6 +173,7 @@ static int
initramfs_init(struct fs_info *info)
{
initramfs = get_module("/boot/initramfs.tar", &initramfs_size);
+ info->caps = FSCAP_FULLPATH;
if (initramfs == NULL) {
panic("Failed to load initramfs\n");
@@ -221,7 +222,7 @@ initramfs_open(const char *path)
}
hdr = initramfs_from_path((void *)initramfs, path);
- return hdr_to_contents(hdr);
+ return (hdr == NULL) ? NULL : hdr_to_contents(hdr);
}
struct vfsops g_initramfs_ops = {
diff --git a/sys/include/arch/amd64/cpu.h b/sys/include/arch/amd64/cpu.h
index e2ed851..ee9bad7 100644
--- a/sys/include/arch/amd64/cpu.h
+++ b/sys/include/arch/amd64/cpu.h
@@ -110,6 +110,46 @@ amd64_read_gs_base(void)
return rdmsr(IA32_KERNEL_GS_BASE);
}
+static inline uint64_t
+amd64_read_cr0(void)
+{
+ uint64_t cr0;
+ __ASMV("mov %%cr0, %0" : "=r" (cr0) :: "memory");
+ return cr0;
+}
+
+static inline void
+amd64_write_cr0(uint64_t val)
+{
+ __ASMV("mov %0, %%cr0" :: "r" (val) : "memory");
+}
+
+static inline uint64_t
+amd64_read_cr4(void)
+{
+ uint64_t cr4;
+ __ASMV("mov %%cr4, %0" : "=r" (cr4) :: "memory");
+ return cr4;
+}
+
+static inline void
+amd64_write_cr4(uint64_t val)
+{
+ __ASMV("mov %0, %%cr4" :: "r" (val) : "memory");
+}
+
+static inline void
+amd64_fxsave(void *area)
+{
+ __ASMV("fxsave (%0)" :: "r" (area) : "memory");
+}
+
+static inline void
+amd64_fxrstor(void *area)
+{
+ __ASMV("fxrstor (%0)" :: "r" (area) : "memory");
+}
+
struct cpu_info *amd64_this_cpu(void);
#endif /* !_AMD64_CPU_H_ */
diff --git a/sys/include/arch/amd64/frame.h b/sys/include/arch/amd64/frame.h
index a2e1a05..298a836 100644
--- a/sys/include/arch/amd64/frame.h
+++ b/sys/include/arch/amd64/frame.h
@@ -67,5 +67,12 @@ struct trapframe {
(FRAME)->rsp = SP; \
(FRAME)->ss = 0x10; \
+#define init_frame_user(FRAME, IP, SP) \
+ (FRAME)->rip = IP; \
+ (FRAME)->cs = 0x18 | 3; \
+ (FRAME)->rflags = 0x202; \
+ (FRAME)->rsp = SP; \
+ (FRAME)->ss = 0x20 | 3; \
+
#endif /* !defined(__ASSEMBLER__) */
#endif /* !_AMD64_FRAME_H_ */
diff --git a/sys/include/arch/amd64/pcb.h b/sys/include/arch/amd64/pcb.h
new file mode 100644
index 0000000..0e0aab8
--- /dev/null
+++ b/sys/include/arch/amd64/pcb.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _AMD64_PCB_H_
+#define _AMD64_PCB_H_
+
+#include <sys/types.h>
+
+struct pcb {
+ uint8_t *fpu_state;
+};
+
+#endif /* !_AMD64_PCB_H_ */
diff --git a/sys/include/arch/amd64/trap.h b/sys/include/arch/amd64/trap.h
index 1019999..c75fa28 100644
--- a/sys/include/arch/amd64/trap.h
+++ b/sys/include/arch/amd64/trap.h
@@ -47,6 +47,7 @@
#define TRAP_PROTFLT 9 /* General protection */
#define TRAP_PAGEFLT 10 /* Page fault */
#define TRAP_NMI 11 /* Non-maskable interrupt */
+#define TRAP_SS 12 /* Stack-segment fault */
/* Trap is coming from user mode */
#define TRAP_USER 0x100
@@ -65,6 +66,7 @@ void segnp(void *sf);
void general_prot(void *sf);
void page_fault(void *sf);
void nmi(void *sf);
+void ss_fault(void *sf);
void trap_handler(struct trapframe *tf);
#else
.macro handle_trap
diff --git a/sys/include/sys/filedesc.h b/sys/include/sys/filedesc.h
new file mode 100644
index 0000000..ef74fb1
--- /dev/null
+++ b/sys/include/sys/filedesc.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_FILEDESC_H_
+#define _SYS_FILEDESC_H_
+
+#include <sys/vnode.h>
+#include <sys/spinlock.h>
+#include <sys/types.h>
+
+struct proc;
+
+struct filedesc {
+ int fdno;
+ off_t offset;
+ bool is_dir;
+ struct vnode *vnode;
+ struct spinlock lock;
+};
+
+#if defined(_KERNEL)
+struct filedesc *fd_alloc(struct proc *td);
+struct filedesc *fd_from_fdnum(const struct proc *td, int fdno);
+void fd_close_fdnum(struct proc *td, int fdno);
+#endif
+
+#endif
diff --git a/sys/include/sys/loader.h b/sys/include/sys/loader.h
index c1aa426..74a325c 100644
--- a/sys/include/sys/loader.h
+++ b/sys/include/sys/loader.h
@@ -33,17 +33,22 @@
#include <sys/types.h>
#include <vm/pmap.h>
-#define AT_NULL 0
-#define AT_IGNORE 1
-#define AT_EXECFD 2
-#define AT_PHDR 3
-#define AT_PHENT 4
-#define AT_PHNUM 5
-#define AT_PAGESZ 6
-#define AT_BASE 7
-#define AT_FLAGS 8
-#define AT_ENTRY 9
-#define AT_SECURE 10
+/* DANGER!: DO NOT CHANGE THESE DEFINES */
+#define AT_NULL 0
+#define AT_ENTRY 1
+#define AT_PHDR 2
+#define AT_PHENT 3
+#define AT_PHNUM 4
+#define AT_EXECPATH 5
+#define AT_SECURE 6
+#define AT_RANDOM 7
+#define AT_EXECFN 8
+
+#define STACK_PUSH(ptr, val) *(--ptr) = val
+#define AUXVAL(ptr, tag, val) __extension__ ({ \
+ STACK_PUSH(ptr, val); \
+ STACK_PUSH(ptr, tag); \
+});
/* Auxiliary Vector */
struct auxval {
diff --git a/sys/include/sys/machdep.h b/sys/include/sys/machdep.h
index 713b7db..0c06374 100644
--- a/sys/include/sys/machdep.h
+++ b/sys/include/sys/machdep.h
@@ -32,11 +32,15 @@
#include <sys/types.h>
#include <sys/cdefs.h>
+#include <sys/proc.h>
#if defined(_KERNEL)
#define MAXCPUS 32
+int processor_init_pcb(struct proc *proc);
+int processor_free_pcb(struct proc *proc);
+void processor_switch_to(struct proc *old_td, struct proc *new_td);
void processor_init(void);
void processor_halt(void);
void intr_mask(void);
diff --git a/sys/include/sys/mount.h b/sys/include/sys/mount.h
index 3ac7ec7..209fa3e 100644
--- a/sys/include/sys/mount.h
+++ b/sys/include/sys/mount.h
@@ -33,6 +33,7 @@
#include <sys/types.h>
#include <sys/queue.h>
#include <sys/vnode.h>
+#include <sys/cdefs.h>
#define FS_NAME_MAX 16 /* Max length of FS type name including nul */
@@ -54,9 +55,15 @@ struct fs_info {
char name[FS_NAME_MAX]; /* Filesystem type name */
struct vfsops *vfsops; /* Filesystem operations */
struct mount *mp_root;
+ uint16_t caps;
};
/*
+ * Filesystem capabilities
+ */
+#define FSCAP_FULLPATH __BIT(0) /* Requires full path per lookup */
+
+/*
* Mount flags
*/
#define MNT_RDONLY 0x00000001
diff --git a/sys/include/sys/proc.h b/sys/include/sys/proc.h
index f45e4c6..c6046d7 100644
--- a/sys/include/sys/proc.h
+++ b/sys/include/sys/proc.h
@@ -32,8 +32,13 @@
#include <sys/types.h>
#include <sys/queue.h>
+#include <sys/filedesc.h>
#include <machine/cpu.h>
#include <machine/frame.h>
+#include <machine/pcb.h>
+#include <vm/vm.h>
+
+#define PROC_MAX_FDS 256
/*
* A task running on the CPU e.g., a process or
@@ -43,6 +48,11 @@ struct proc {
pid_t pid;
struct cpu_info *cpu;
struct trapframe *tf;
+ struct pcb pcb;
+ struct vas addrsp;
+ uintptr_t stack_base;
+ uint8_t is_user;
+ struct filedesc *fds[PROC_MAX_FDS];
TAILQ_ENTRY(proc) link;
};
diff --git a/sys/include/sys/sched.h b/sys/include/sys/sched.h
index d803df0..1fa947e 100644
--- a/sys/include/sys/sched.h
+++ b/sys/include/sys/sched.h
@@ -37,7 +37,9 @@
#include <machine/cpu.h>
#include <machine/frame.h>
+struct proc *this_td(void);
void sched_init(void);
+void sched_exit(void);
void sched_context_switch(struct trapframe *tf);
__noreturn
diff --git a/sys/include/sys/syscall.h b/sys/include/sys/syscall.h
new file mode 100644
index 0000000..66dc5f3
--- /dev/null
+++ b/sys/include/sys/syscall.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_SYSCALL_H_
+#define _SYS_SYSCALL_H_
+
+#include <sys/types.h>
+#if defined(_KERNEL)
+#include <machine/frame.h>
+#endif
+
+/* Do not reorder */
+enum {
+ SYS_exit = 1,
+ __MAX_SYSCALLS
+};
+
+struct syscall_args {
+ uint64_t code;
+ uint64_t arg0, arg1, arg2, arg3, arg4;
+ uint64_t ip;
+ uint64_t sp;
+};
+
+#if defined(_KERNEL)
+extern uint64_t(*g_syscall_table[__MAX_SYSCALLS])(struct syscall_args *args);
+void __syscall(struct trapframe *tf);
+#endif
+
+#endif
diff --git a/sys/include/sys/vfs.h b/sys/include/sys/vfs.h
index a684c3f..c1bef53 100644
--- a/sys/include/sys/vfs.h
+++ b/sys/include/sys/vfs.h
@@ -42,7 +42,7 @@ void vfs_init(void);
struct fs_info *vfs_byname(const char *name);
int vfs_vget(struct vnode *parent, const char *name, struct vnode **vp);
-struct vnode *vfs_path_to_node(const char *path);
+int vfs_path_to_node(const char *path, struct vnode **vp);
char *vfs_get_fname_at(const char *path, size_t idx);
int vfs_rootname(const char *path, char **new_path);
bool vfs_is_valid_path(const char *path);
diff --git a/sys/include/sys/vnode.h b/sys/include/sys/vnode.h
index f584356..545e38f 100644
--- a/sys/include/sys/vnode.h
+++ b/sys/include/sys/vnode.h
@@ -47,6 +47,7 @@ struct vnode {
struct mount *mp; /* Ptr to vfs vnode is in */
struct vops *vops;
struct vnode *parent;
+ struct fs_info *fs; /* Filesystem this vnode belongs to, can be NULL */
void *data; /* Filesystem specific data */
};
diff --git a/sys/include/vm/pmap.h b/sys/include/vm/pmap.h
index ebabd32..3380199 100644
--- a/sys/include/vm/pmap.h
+++ b/sys/include/vm/pmap.h
@@ -90,6 +90,12 @@ struct vas pmap_read_vas(void);
int pmap_map(struct vm_ctx *, struct vas, vaddr_t, paddr_t, vm_prot_t);
/*
+ * Get rid of a virtual address space and free
+ * resources.
+ */
+int pmap_free_vas(struct vm_ctx *, struct vas);
+
+/*
* Unmap a page.
*/
int pmap_unmap(struct vm_ctx *, struct vas, vaddr_t);
diff --git a/sys/include/vm/vm.h b/sys/include/vm/vm.h
index 2a24d76..48e1b8f 100644
--- a/sys/include/vm/vm.h
+++ b/sys/include/vm/vm.h
@@ -61,5 +61,6 @@ vm_get_page_size(void)
void vm_init(void);
struct vm_ctx *vm_get_ctx(void);
+struct vas vm_get_kvas(void);
#endif /* !_VM_H_ */
diff --git a/sys/kern/kern_filedesc.c b/sys/kern/kern_filedesc.c
new file mode 100644
index 0000000..a943714
--- /dev/null
+++ b/sys/kern/kern_filedesc.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/filedesc.h>
+#include <sys/proc.h>
+#include <sys/sched.h>
+#include <vm/dynalloc.h>
+#include <assert.h>
+#include <string.h>
+
+/*
+ * Allocate a file descriptor.
+ *
+ * @td: Thread to allocate from, NULL for current thread.
+ */
+struct filedesc *
+fd_alloc(struct proc *td)
+{
+ struct filedesc *fd;
+
+ if (td == NULL) {
+ td = this_td();
+ __assert(td != NULL);
+ }
+
+ for (size_t i = 0; i < PROC_MAX_FDS; ++i) {
+ if (td->fds[i] != NULL) {
+ continue;
+ }
+
+ fd = dynalloc(sizeof(struct filedesc));
+ memset(fd, 0, sizeof(struct filedesc));
+
+ if (fd == NULL) {
+ return NULL;
+ }
+
+ fd->fdno = i;
+ td->fds[i] = fd;
+ return fd;
+ }
+
+ return NULL;
+}
+
+/*
+ * Fetch a file descriptor from a file descriptor
+ * number.
+ *
+ * @td: Thread to fetch from, NULL for current thread.
+ * @fdno: File descriptor to fetch
+ */
+struct filedesc *
+fd_from_fdnum(const struct proc *td, int fdno)
+{
+ if (td == NULL) {
+ td = this_td();
+ __assert(td != NULL);
+ }
+
+ if (fdno < 0 || fdno > PROC_MAX_FDS) {
+ return NULL;
+ }
+
+ for (size_t i = 0; i < PROC_MAX_FDS; ++i) {
+ if (i == fdno && td->fds[i] != NULL) {
+ return td->fds[i];
+ }
+ }
+
+ return NULL;
+}
+
+/*
+ * Close a file descriptor from its fd number.
+ *
+ * @td: Thread to fetch from, NULL for current thread.
+ * @fdno: File descriptor number to close.
+ */
+void
+fd_close_fdnum(struct proc *td, int fdno)
+{
+ struct filedesc *fd;
+
+ if (td == NULL) {
+ td = this_td();
+ __assert(td != NULL);
+ }
+
+ fd = fd_from_fdnum(td, fdno);
+ if (fd == NULL) {
+ return;
+ }
+
+ dynfree(fd);
+ td->fds[fdno] = NULL;
+}
diff --git a/sys/kern/kern_loader.c b/sys/kern/kern_loader.c
index 53ba8c2..23249ea 100644
--- a/sys/kern/kern_loader.c
+++ b/sys/kern/kern_loader.c
@@ -61,12 +61,10 @@ int loader_load(struct vas vas, const void *dataptr, struct auxval *auxv,
vm_prot_t prot = PROT_USER;
uintptr_t physmem;
- uintptr_t max_addr, map_addr;
- size_t misalign, page_count;
-
+ size_t misalign, page_count, map_len;
int status;
- const size_t GRANULE = vm_get_page_size();
+ const size_t GRANULE = vm_get_page_size();
void *tmp_ptr;
if (auxv == NULL) {
@@ -93,26 +91,8 @@ int loader_load(struct vas vas, const void *dataptr, struct auxval *auxv,
misalign = phdr->p_vaddr & (GRANULE - 1);
page_count = __DIV_ROUNDUP(phdr->p_memsz + misalign, GRANULE);
- max_addr = phdr->p_vaddr + (GRANULE * page_count);
-
- /*
- * We are assuming this is a user program that we are loading.
- * All user programs should be on the lower half of the address
- * space. We will check that before we begin doing anything here.
- *
- * We are also going to check if the virtual address the program
- * header refers to overflows into the higher half. If anything
- * goes into the higher half, we won't simply drop the phdr,
- * we'll instead assume caller error and return -EINVAL.
- */
- if (phdr->p_vaddr >= VM_HIGHER_HALF) {
- return -EINVAL;
- } else if (max_addr >= VM_HIGHER_HALF) {
- /* Overflows into higher half */
- return -EINVAL;
- }
-
physmem = vm_alloc_pageframe(page_count);
+ map_len = page_count * GRANULE;
/* Do we not have enough page frames? */
if (physmem == 0) {
@@ -121,14 +101,9 @@ int loader_load(struct vas vas, const void *dataptr, struct auxval *auxv,
return -ENOMEM;
}
- map_addr = phdr->p_vaddr + load_base;
- status = vm_map_create(vas, map_addr, physmem, prot, page_count*GRANULE);
+ status = vm_map_create(vas, phdr->p_vaddr + load_base, physmem, prot, map_len);
if (status != 0) {
- DBG("Failed to map 0x%p - 0x%p\n",
- phdr->p_vaddr + load_base,
- (phdr->p_vaddr + load_base) + (page_count * GRANULE));
-
return status;
}
diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c
index f61c592..7b3776d 100644
--- a/sys/kern/kern_sched.c
+++ b/sys/kern/kern_sched.c
@@ -34,10 +34,36 @@
#include <sys/timer.h>
#include <sys/cdefs.h>
#include <sys/spinlock.h>
+#include <sys/loader.h>
+#include <sys/panic.h>
+#include <sys/machdep.h>
+#include <sys/filedesc.h>
+#include <fs/initramfs.h>
#include <vm/dynalloc.h>
+#include <vm/physseg.h>
+#include <vm/pmap.h>
+#include <vm/map.h>
+#include <vm/vm.h>
#include <assert.h>
#include <string.h>
+#define STACK_PAGES 8
+#define STACK_SIZE (STACK_PAGES*vm_get_page_size())
+
+/*
+ * The PHYS_TO_VIRT/VIRT_TO_PHYS macros convert
+ * addresses to lower and higher half addresses.
+ * Userspace addresses are on the lower half,
+ * therefore, we can just wrap over these to
+ * keep things simple.
+ *
+ * XXX: TODO: This won't work when not identity mapping
+ * lowerhalf addresses. Once that is updated,
+ * get rid of this.
+ */
+#define USER_TO_KERN(user) PHYS_TO_VIRT(user)
+#define KERN_TO_USER(kern) VIRT_TO_PHYS(kern)
+
/*
* Thread ready queue - all threads ready to be
* scheduled should be added to this queue.
@@ -51,9 +77,6 @@ static size_t nthread = 0;
*/
static struct spinlock tdq_lock = {0};
-/* In sys/<machine>/<machine>/switch.S */
-void __sched_switch_to(struct trapframe *tf);
-
static inline void
sched_oneshot(void)
{
@@ -97,13 +120,11 @@ sched_dequeue_td(void)
spinlock_acquire(&tdq_lock);
- if (TAILQ_EMPTY(&td_queue)) {
- goto done;
+ if (!TAILQ_EMPTY(&td_queue)) {
+ td = TAILQ_FIRST(&td_queue);
+ TAILQ_REMOVE(&td_queue, td, link);
}
- td = TAILQ_FIRST(&td_queue);
- TAILQ_REMOVE(&td_queue, td, link);
-done:
spinlock_release(&tdq_lock);
return td;
}
@@ -121,12 +142,101 @@ sched_enter(void)
}
}
+static uintptr_t
+sched_init_stack(void *stack_top, char *argvp[], char *envp[], struct auxval auxv)
+{
+ uintptr_t *sp = stack_top;
+ void *env_ptr = NULL, *argv_ptr = NULL;
+ size_t argc, envc, len;
+
+ /* Copy argument and environment strings */
+ for (envc = 0; envp[envc] != NULL; ++envc) {
+ len = strlen(envp[envc]);
+ sp -= len - 1;
+ memcpy(sp, envp[envc], len);
+ }
+
+ __assert(envc >= 1);
+ env_ptr = sp;
+
+ for (argc = 0; argvp[argc] != NULL; ++argc) {
+ len = strlen(argvp[argc]);
+ sp -= len - 1;
+ memcpy(sp, argvp[argc], len);
+ }
+
+ __assert(argc >= 1);
+ argv_ptr = sp;
+
+ /* Ensure the stack is aligned */
+ sp = (void *)__ALIGN_DOWN((uintptr_t)sp, 16);
+ if (((argc + envc + 1) & 1) != 0)
+ --sp;
+
+ AUXVAL(sp, AT_NULL, 0x0);
+ AUXVAL(sp, AT_SECURE, 0x0);
+ AUXVAL(sp, AT_ENTRY, auxv.at_entry);
+ AUXVAL(sp, AT_PHDR, auxv.at_phdr);
+ AUXVAL(sp, AT_PHNUM, auxv.at_phnum);
+ STACK_PUSH(sp, 0);
+
+ /* Push environment string pointers */
+ for (int i = 0; i < envc; ++i) {
+ len = strlen(env_ptr);
+ sp -= len;
+
+ *sp = (uintptr_t)KERN_TO_USER((uintptr_t)env_ptr);
+ env_ptr = (char *)env_ptr + len;
+ }
+
+ /* Push argument string pointers */
+ STACK_PUSH(sp, 0);
+ for (int i = 0; i < argc; ++i) {
+ len = strlen(argv_ptr);
+ sp -= len;
+
+ *sp = (uintptr_t)KERN_TO_USER((uintptr_t)argv_ptr);
+ argv_ptr = (char *)argv_ptr + len;
+ }
+
+ STACK_PUSH(sp, argc);
+
+ return (uintptr_t)sp;
+}
+
+static uintptr_t
+sched_create_stack(struct vas vas, bool user, char *argvp[],
+ char *envp[], struct auxval auxv, struct proc *td)
+{
+ int status;
+ uintptr_t stack;
+ const vm_prot_t USER_STACK_PROT = PROT_WRITE | PROT_USER;
+
+ if (!user) {
+ stack = (uintptr_t)dynalloc(STACK_SIZE);
+ td->stack_base = (uintptr_t)stack;
+ return sched_init_stack((void *)(stack + STACK_SIZE), argvp, envp, auxv);
+ }
+
+ stack = vm_alloc_pageframe(STACK_PAGES);
+ td->stack_base = stack;
+ status = vm_map_create(vas, stack, stack, USER_STACK_PROT, STACK_SIZE);
+
+ if (status != 0) {
+ return 0;
+ }
+
+ memset(USER_TO_KERN(stack), 0, STACK_SIZE);
+ stack = sched_init_stack((void *)USER_TO_KERN(stack + STACK_SIZE), argvp, envp, auxv);
+ return stack;
+}
+
static struct proc *
-sched_create_td(uintptr_t rip)
+sched_create_td(uintptr_t rip, char *argvp[], char *envp[], struct auxval auxv,
+ struct vas vas, bool is_user)
{
- const size_t STACK_SIZE = 0x100000; /* 1 MiB */
struct proc *td;
- void *stack;
+ uintptr_t stack;
struct trapframe *tf;
tf = dynalloc(sizeof(struct trapframe));
@@ -134,32 +244,103 @@ sched_create_td(uintptr_t rip)
return NULL;
}
- stack = dynalloc(STACK_SIZE);
- if (stack == NULL) {
+ td = dynalloc(sizeof(struct proc));
+ if (td == NULL) {
+ /* TODO: Free stack */
dynfree(tf);
return NULL;
}
- td = dynalloc(sizeof(struct proc));
- if (td == NULL) {
+ stack = sched_create_stack(vas, is_user, argvp, envp, auxv, td);
+ if (stack == 0) {
dynfree(tf);
- dynfree(stack);
+ dynfree(td);
return NULL;
}
memset(tf, 0, sizeof(struct trapframe));
- memset(stack, 0, STACK_SIZE);
+ memset(td, 0, sizeof(struct proc));
/* Setup process itself */
td->pid = 0; /* Don't assign PID until enqueued */
td->cpu = NULL; /* Not yet assigned a core */
td->tf = tf;
+ td->addrsp = vas;
+ td->is_user = is_user;
+ processor_init_pcb(td);
+
+ /* Allocate standard file descriptors */
+ __assert(fd_alloc(td) != NULL); /* STDIN */
+ __assert(fd_alloc(td) != NULL); /* STDOUT */
+ __assert(fd_alloc(td) != NULL); /* STDERR */
/* Setup trapframe */
- init_frame(tf, rip, (uintptr_t)stack + STACK_SIZE - 1);
+ if (!is_user) {
+ init_frame(tf, rip, (uintptr_t)stack);
+ } else {
+ init_frame_user(tf, rip, KERN_TO_USER(stack));
+ }
return td;
}
+static void
+sched_destroy_td(struct proc *td)
+{
+ processor_free_pcb(td);
+
+ /*
+ * User stacks are allocated with vm_alloc_pageframe(),
+ * while kernel stacks are allocated with dynalloc().
+ * We want to check if we are a user program or kernel
+ * program to perform the proper deallocation method.
+ */
+ if (td->is_user) {
+ vm_free_pageframe(td->stack_base, STACK_PAGES);
+ } else {
+ dynfree((void *)td->stack_base);
+ }
+
+ /* Close all of the file descriptors */
+ for (size_t i = 0; i < PROC_MAX_FDS; ++i) {
+ fd_close_fdnum(td, i);
+ }
+
+ pmap_free_vas(vm_get_ctx(), td->addrsp);
+ dynfree(td);
+}
+
+void
+sched_exit(void)
+{
+ struct proc *td;
+ struct vas kvas = vm_get_kvas();
+
+ intr_mask();
+
+ td = this_td();
+
+ /* Switch back to the kernel address space and destroy ourself */
+ pmap_switch_vas(vm_get_ctx(), kvas);
+ sched_destroy_td(td);
+
+ intr_unmask();
+ sched_enter();
+}
+
+/*
+ * Get the current running thread.
+ */
+struct proc *
+this_td(void)
+{
+ struct sched_state *state;
+ struct cpu_info *ci;
+
+ ci = this_cpu();
+ state = &ci->sched_state;
+ return state->td;
+}
+
/*
* Thread context switch routine
*/
@@ -174,43 +355,73 @@ sched_context_switch(struct trapframe *tf)
* If we have no threads, we should not
* preempt at all.
*/
- if (nthread == 0) {
- goto done;
- } else if ((next_td = sched_dequeue_td()) == NULL) {
- /* Empty */
- goto done;
+ if (nthread == 0 || (next_td = sched_dequeue_td()) == NULL) {
+ sched_oneshot();
+ return;
}
+ /*
+ * If we have a thread currently running and we are switching
+ * to another, we shall save our current register state
+ * by copying the trapframe.
+ */
if (state->td != NULL) {
- /* Save our trapframe */
td = state->td;
memcpy(td->tf, tf, sizeof(struct trapframe));
}
- /* Copy to stack */
+ /* Copy over the next thread's register state to us */
memcpy(tf, next_td->tf, sizeof(struct trapframe));
td = state->td;
state->td = next_td;
+ /* Re-enqueue the previous thread if it exists */
if (td != NULL) {
sched_enqueue_td(td);
}
-done:
+
+ /* Do architecture specific context switch logic */
+ processor_switch_to(td, next_td);
+
+ /* Done, switch out our vas and oneshot */
+ pmap_switch_vas(vm_get_ctx(), next_td->addrsp);
sched_oneshot();
}
void
sched_init(void)
{
+ struct proc *init;
+ struct auxval auxv = {0}, ld_auxv = {0};
+ struct vas vas = pmap_create_vas(vm_get_ctx());
+ const char *init_bin, *ld_bin;
+
+ char *ld_path;
+ char *argv[] = {"/usr/sbin/init", NULL};
+ char *envp[] = {"", NULL};
+
TAILQ_INIT(&td_queue);
- /*
- * TODO: Create init with sched_create_td()
- * and enqueue with sched_enqueue_td()
- */
- (void)sched_create_td;
- (void)sched_enqueue_td;
+ if ((init_bin = initramfs_open("/usr/sbin/init")) == NULL) {
+ panic("Could not open /usr/boot/init\n");
+ }
+ if (loader_load(vas, init_bin, &auxv, 0, &ld_path) != 0) {
+ panic("Could not load init\n");
+ }
+ if ((ld_bin = initramfs_open(ld_path)) == NULL) {
+ panic("Could not open %s\n", ld_path);
+ }
+ if (loader_load(vas, ld_bin, &ld_auxv, 0x00, NULL) != 0) {
+ panic("Could not load %s\n", ld_path);
+ }
+
+ init = sched_create_td((uintptr_t)ld_auxv.at_entry, argv, envp, ld_auxv, vas, true);
+ if (init == NULL) {
+ panic("Failed to create thread for init\n");
+ }
+
+ sched_enqueue_td(init);
}
/*
diff --git a/sys/kern/kern_syscall.c b/sys/kern/kern_syscall.c
new file mode 100644
index 0000000..b6e31d1
--- /dev/null
+++ b/sys/kern/kern_syscall.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/syscall.h>
+#include <sys/sched.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+__noreturn static uint64_t
+sys_exit(struct syscall_args *args)
+{
+ sched_exit();
+ __builtin_unreachable();
+}
+
+uint64_t(*g_syscall_table[__MAX_SYSCALLS])(struct syscall_args *args) = {
+ sys_exit,
+};
diff --git a/sys/kern/vfs_init.c b/sys/kern/vfs_init.c
index 18ab3ac..0d8d194 100644
--- a/sys/kern/vfs_init.c
+++ b/sys/kern/vfs_init.c
@@ -40,8 +40,10 @@ __MODULE_NAME("vfs");
__KERNEL_META("$Hyra$: vfs.c, Ian Marco Moffett, "
"Hyra Virtual File System");
+#define INITRAMFS_ID 0
+
static struct fs_info filesystems[] = {
- { "initramfs", &g_initramfs_ops }
+ [INITRAMFS_ID] = { "initramfs", &g_initramfs_ops }
};
struct vnode *g_root_vnode = NULL;
@@ -76,4 +78,5 @@ vfs_init(void)
}
g_root_vnode->vops = &g_initramfs_vops;
+ g_root_vnode->fs = &filesystems[INITRAMFS_ID];
}
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
index 748d5e2..1398964 100644
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -29,11 +29,13 @@
#include <sys/types.h>
#include <sys/vfs.h>
+#include <sys/mount.h>
+#include <sys/errno.h>
#include <vm/dynalloc.h>
#include <string.h>
/*
- * Fetches the filename within a past at
+ * Fetches the filename within a path at
* the nth index denoted by `idx'
*
* Returns memory allocated by dynalloc()
@@ -115,9 +117,58 @@ vfs_get_fname_at(const char *path, size_t idx)
return ret;
}
-struct vnode *
-vfs_path_to_node(const char *path)
+/*
+ * Fetches a vnode from a path.
+ *
+ * @path: Path to fetch vnode from.
+ * @vp: Output var for fetched vnode.
+ *
+ * Returns 0 on success.
+ */
+int
+vfs_path_to_node(const char *path, struct vnode **vp)
{
- /* TODO */
- return NULL;
+ struct vnode *vnode = g_root_vnode;
+ struct fs_info *fs;
+ char *name;
+ int s = 0, fs_caps = 0;
+
+ if (strcmp(path, "/") == 0 || !vfs_is_valid_path(path)) {
+ return -1;
+ } else if (*path != '/') {
+ return -1;
+ }
+
+ /* Fetch filesystem capabilities if we can */
+ if (vnode->fs != NULL) {
+ fs = vnode->fs;
+ fs_caps = fs->caps;
+ }
+
+ /*
+ * If the filesystem requires full-path lookups, we can try
+ * throwing the full path at the filesystem to see if
+ * it'll give us a vnode.
+ */
+ if (__TEST(fs_caps, FSCAP_FULLPATH)) {
+ s = vfs_vget(g_root_vnode, path, &vnode);
+ goto done;
+ }
+
+ for (size_t i = 0;; ++i) {
+ name = vfs_get_fname_at(path, i);
+ if (name == NULL) break;
+
+ s = vfs_vget(vnode, name, &vnode);
+ dynfree(name);
+
+ if (s != 0) break;
+ }
+
+done:
+ if (vp != NULL && s == 0) {
+ *vp = vnode;
+ }
+
+ return s;
}
diff --git a/sys/vm/vm_init.c b/sys/vm/vm_init.c
index f15cb0b..6096059 100644
--- a/sys/vm/vm_init.c
+++ b/sys/vm/vm_init.c
@@ -59,6 +59,15 @@ vm_get_ctx(void)
return &bsp_vm_ctx;
}
+/*
+ * Return the kernel VAS.
+ */
+struct vas
+vm_get_kvas(void)
+{
+ return kernel_vas;
+}
+
void
vm_init(void)
{
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 0d27738..f65bad2 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -78,12 +78,13 @@ int
vm_map_create(struct vas vas, vaddr_t va, paddr_t pa, vm_prot_t prot, size_t bytes)
{
size_t granule = vm_get_page_size();
+ size_t misalign = va & (granule - 1);
int s;
struct vm_ctx *ctx = vm_get_ctx();
/* We want bytes to be aligned by the granule */
- bytes = __ALIGN_UP(bytes, granule);
+ bytes = __ALIGN_UP(bytes + misalign, granule);
/* Align VA/PA by granule */
va = __ALIGN_DOWN(va, granule);
@@ -115,10 +116,11 @@ vm_map_destroy(struct vas vas, vaddr_t va, size_t bytes)
{
struct vm_ctx *ctx = vm_get_ctx();
size_t granule = vm_get_page_size();
+ size_t misalign = va & (granule - 1);
int s;
/* We want bytes to be aligned by the granule */
- bytes = __ALIGN_UP(bytes, granule);
+ bytes = __ALIGN_UP(bytes + misalign, granule);
/* Align VA by granule */
va = __ALIGN_DOWN(va, granule);
diff --git a/tools/cross.sh b/tools/cross.sh
index 5a0784a..52e7b1b 100644
--- a/tools/cross.sh
+++ b/tools/cross.sh
@@ -140,7 +140,7 @@ rm -rf $GCC_NAME-copy
echo "Configuring $GCC_NAME..."
mkdir build-gcc
cd build-gcc
-../$GCC_NAME/configure --target="$TARGET" --with-sysroot=/ --prefix="$PREFIX" --disable-nls --enable-languages=c --disable-multilib
+../$GCC_NAME/configure --target="$TARGET" --with-sysroot=/ --prefix="$PREFIX" --disable-nls --enable-languages=c,c++,lto --disable-multilib
echo "Building all-gcc..."
$MAKE all-gcc -j"$CORES"
echo "Building all-target-libgcc..."
diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile
new file mode 100644
index 0000000..c75ebd0
--- /dev/null
+++ b/usr.sbin/Makefile
@@ -0,0 +1,7 @@
+CC =
+LD =
+LDSO =
+
+.PHONY: all
+all:
+ cd init/; make LDSO=$(LDSO) CC=$(CC) LD=$(LD)
diff --git a/usr.sbin/init/Makefile b/usr.sbin/init/Makefile
new file mode 100644
index 0000000..fa65c8d
--- /dev/null
+++ b/usr.sbin/init/Makefile
@@ -0,0 +1,8 @@
+CC =
+LD =
+LDSO =
+
+.PHONY: all
+all:
+ $(CC) -c main.c -o main.o;
+ $(LD) --dynamic-linker /usr/lib/ld.so $(LDSO) main.o -o init -e main
diff --git a/usr.sbin/init/main.c b/usr.sbin/init/main.c
new file mode 100644
index 0000000..af62d76
--- /dev/null
+++ b/usr.sbin/init/main.c
@@ -0,0 +1,6 @@
+int
+main(void)
+{
+ /* Do nothing */
+ while (1);
+}