From 19af24b8a42f349361a8a604f5ad758f65addd32 Mon Sep 17 00:00:00 2001 From: Ry Date: Thu, 19 May 2022 14:15:40 -0700 Subject: [PATCH] fox32os: Initial commit --- LICENSE | 21 +++++++++ base_image/startup.cfg | 1 + build.sh | 20 ++++++++ build/ryfs | 1 + kernel/allocator.asm | 35 ++++++++++++++ kernel/fxf/FXF specification.md | 12 +++++ kernel/fxf/fxf.asm | 24 ++++++++++ kernel/fxf/reloc.asm | 64 +++++++++++++++++++++++++ kernel/main.asm | 82 +++++++++++++++++++++++++++++++++ 9 files changed, 260 insertions(+) create mode 100644 LICENSE create mode 100644 base_image/startup.cfg create mode 100755 build.sh create mode 160000 build/ryfs create mode 100644 kernel/allocator.asm create mode 100644 kernel/fxf/FXF specification.md create mode 100644 kernel/fxf/fxf.asm create mode 100644 kernel/fxf/reloc.asm create mode 100644 kernel/main.asm diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e3189df --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 ryfox/ry755 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/base_image/startup.cfg b/base_image/startup.cfg new file mode 100644 index 0000000..d914b91 --- /dev/null +++ b/base_image/startup.cfg @@ -0,0 +1 @@ +demo fxf diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..89ddd85 --- /dev/null +++ b/build.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +set -e + +mkdir -p base_image + +# if fox32os.img doesn't exist, then create it +if [ ! -f fox32os.img ]; then + echo "fox32os.img not found, creating it" + build/ryfs/ryfs.py -s 16777216 -l fox32os create fox32os.img +fi + +echo "assembling kernel" +../fox32asm/target/release/fox32asm kernel/main.asm base_image/system.bin + +echo "adding files to fox32os.img" +cd base_image +for file in "./*"; do + ../build/ryfs/ryfs.py add ../fox32os.img $file +done diff --git a/build/ryfs b/build/ryfs new file mode 160000 index 0000000..a1f18bb --- /dev/null +++ b/build/ryfs @@ -0,0 +1 @@ +Subproject commit a1f18bbc3c8891f98f98fb915fb2551af1ef6477 diff --git a/kernel/allocator.asm b/kernel/allocator.asm new file mode 100644 index 0000000..17a9282 --- /dev/null +++ b/kernel/allocator.asm @@ -0,0 +1,35 @@ +; memory allocator routines +; this is a very basic memory allocator, it doesn't even allow freeing +; TODO: make this better + +const MEMORY_TOP: 0x02000000 + +; allocate a block of memory +; inputs: +; r0: size in bytes +; outputs: +; r0: pointer to allocated block (or zero if no blocks free) +allocate_memory: + push r1 + push r2 + + mov r1, MEMORY_TOP + mov r2, [free_base] + sub r1, r2 + cmp r1, r0 + iflteq jmp allocate_memory_full + mov r1, [free_base] + add [free_base], r0 + mov r0, r1 + + pop r2 + pop r1 + ret +allocate_memory_full: + mov r0, 0 + + pop r2 + pop r1 + ret + +free_base: data.32 kernel_bottom diff --git a/kernel/fxf/FXF specification.md b/kernel/fxf/FXF specification.md new file mode 100644 index 0000000..268ddc3 --- /dev/null +++ b/kernel/fxf/FXF specification.md @@ -0,0 +1,12 @@ +| Byte Range | Description | +| :-------------------: | -------------------------- | +| 0x00000000-0x00000002 | "FXF" magic bytes | +| 0x00000003 | header version (must be 0) | +| 0x00000004-0x00000007 | code size | +| 0x00000008-0x0000000B | pointer to code | +| 0x0000000C-0x0000000F | `extern` table size | +| 0x00000010-0x00000013 | pointer to `extern` table | +| 0x00000014-0x00000017 | `global` table size | +| 0x00000018-0x0000001B | pointer to `global` table | +| 0x0000001C-0x0000001F | reloc table size | +| 0x00000020-0x00000023 | pointer to reloc table | diff --git a/kernel/fxf/fxf.asm b/kernel/fxf/fxf.asm new file mode 100644 index 0000000..0526321 --- /dev/null +++ b/kernel/fxf/fxf.asm @@ -0,0 +1,24 @@ +; FXF routines + +; parse and relocate an FXF binary loaded in memory +; inputs: +; r0: pointer to memory buffer containing an FXF binary +; outputs: +; none +execute_fxf_binary: + ; TODO: check the magic bytes and header version + + call fxf_reloc + + jmp r0 + + #include "fxf/reloc.asm" + +const FXF_CODE_SIZE: 0x00000004 +const FXF_CODE_PTR: 0x00000008 +const FXF_EXTERN_SIZE: 0x0000000C +const FXF_EXTERN_PTR: 0x00000010 +const FXF_GLOABL_SIZE: 0x00000014 +const FXF_GLOBAL_PTR: 0x00000018 +const FXF_RELOC_SIZE: 0x0000001C +const FXF_RELOC_PTR: 0x00000020 diff --git a/kernel/fxf/reloc.asm b/kernel/fxf/reloc.asm new file mode 100644 index 0000000..ae7941e --- /dev/null +++ b/kernel/fxf/reloc.asm @@ -0,0 +1,64 @@ +; FXF relocation routines + +; relocate a FXF binary +; inputs: +; r0: pointer to memory buffer containing a FXF binary +; outputs: +; r0: relocation address +fxf_reloc: + push r1 + push r2 + push r3 + push r4 + push r5 + + ; calculate relocation address + mov r5, r0 + add r5, FXF_CODE_PTR + mov r5, [r5] + add r5, r0 + + ; get the number of entries in the reloc table + mov r1, r0 + add r1, FXF_RELOC_SIZE + mov r1, [r1] + div r1, 4 + mov r31, r1 + + ; get the pointer to the table + mov r1, r0 + add r1, FXF_RELOC_PTR + mov r1, [r1] + add r1, r0 + + ; get the pointer to the code + mov r2, r0 + add r2, FXF_CODE_PTR + mov r2, [r2] + add r2, r0 + + ; loop over the reloc table entries and relocate the code +fxf_reloc_loop: + ; get the reloc table entry + mov r3, [r1] + + ; point to the location in the code + mov r4, r2 + add r4, r3 + + ; relocate + add [r4], r5 + + ; increment the reloc table pointer + add r1, 4 + loop fxf_reloc_loop + + ; return relocation address + mov r0, r5 + + pop r5 + pop r4 + pop r3 + pop r2 + pop r1 + ret diff --git a/kernel/main.asm b/kernel/main.asm new file mode 100644 index 0000000..46b821c --- /dev/null +++ b/kernel/main.asm @@ -0,0 +1,82 @@ +; fox32os kernel + + org 0x00000800 + +const FOX32OS_VERSION_MAJOR: 0 +const FOX32OS_VERSION_MINOR: 1 +const FOX32OS_VERSION_PATCH: 0 + +const BACKGROUND_COLOR: 0xFF674764 +const TEXT_COLOR: 0xFFFFFFFF + + ; initialization code +entry: + ; clear the background + mov r0, BACKGROUND_COLOR + call fill_background + +draw_startup_text: + mov r0, startup_str + mov r1, 16 + mov r2, 464 + mov r3, TEXT_COLOR + mov r4, 0x00000000 + mov r10, FOX32OS_VERSION_MAJOR + mov r11, FOX32OS_VERSION_MINOR + mov r12, FOX32OS_VERSION_PATCH + call draw_format_str_to_background + + ; open startup.cfg + mov r0, startup_file + mov r1, 0 + mov r2, startup_file_struct + call ryfs_open + cmp r0, 0 + ifz jmp startup_error + + ; load the first 11 bytes of startup.cfg, overwriting the "startup cfg" string + mov r0, 11 + mov r1, startup_file_struct + mov r2, startup_file + call ryfs_read + + ; open the actual startup file + mov r0, startup_file + mov r1, 0 + mov r2, startup_file_struct + call ryfs_open + cmp r0, 0 + ifz jmp startup_error + + ; read the startup file into memory starting at the bottom of the kernel + mov r0, startup_file_struct + mov r1, kernel_bottom + call ryfs_read_whole_file + + ; relocate and execute it!!! + mov r0, kernel_bottom + call execute_fxf_binary + + rjmp 0 + +startup_error: + mov r0, startup_error_str + mov r1, 16 + mov r2, 16 + mov r3, TEXT_COLOR + mov r4, 0x00000000 + call draw_str_to_background + rjmp 0 + + #include "allocator.asm" + #include "fxf/fxf.asm" + +startup_str: data.str "fox32 - OS version %u.%u.%u" data.8 0 + +startup_file: data.str "startup cfg" +startup_error_str: data.str "startup.cfg is invalid" data.8 0 +startup_file_struct: data.32 0 data.32 0 + + #include "../../fox32rom/fox32rom.def" + +kernel_bottom: