diff options
-rw-r--r-- | .github/workflows/cicd.yml | 4 | ||||
-rw-r--r-- | Makefile.in | 46 | ||||
-rw-r--r-- | README.md | 11 | ||||
-rw-r--r-- | configure.ac | 3 | ||||
-rwxr-xr-x | hyra-build.sh | 174 | ||||
-rw-r--r-- | sys/dev/cons/cons.c | 114 | ||||
-rw-r--r-- | sys/include/dev/cons/cons.h | 1 | ||||
-rw-r--r-- | sys/kern/init_main.c | 5 | ||||
-rw-r--r-- | sys/kern/kern_syslog.c | 14 |
9 files changed, 275 insertions, 97 deletions
diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index ad6d236..c56641e 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -20,5 +20,5 @@ jobs: run: sudo apt-get install -y lld clang xorriso - name: Bootstrap and configure run: ./bootstrap && ./configure - - name: Build world with clang - run: make + - name: Build world + run: ./hyra-build.sh -i diff --git a/Makefile.in b/Makefile.in index d3bef70..1270a21 100644 --- a/Makefile.in +++ b/Makefile.in @@ -4,6 +4,7 @@ override PROMPT := printf "%s\t\t%s\n" ############################### # CFLAGS, QEMU flags + misc ############################### +KBUILD_ARGS = "" override PROJECT_ROOT = @PROJECT_ROOT@ override BOOT_FW = @BOOT_FW@ override ARCH = @ARCH@ @@ -12,16 +13,10 @@ override PROMPT := printf "%s\t\t%s\n" override KERNEL_CFLAGS = @KERNEL_CFLAGS@ $(KERNEL_DEFINES) override KERNEL_LDFLAGS = -no-pie -nostdlib -znoexecstack -zmax-page-size=0x1000 -static -Tsys/arch/$(ARCH)/conf/link.ld override QEMU_FLAGS = @QEMU_FLAGS@ -override KERNEL_DEFINES = $ -DHYRA_VERSION="\"$(HYRA_VERSION)\""\ +override KERNEL_DEFINES = $(KBUILD_ARGS) -DHYRA_VERSION="\"$(HYRA_VERSION)\""\ -DHYRA_BUILDDATE="\"@HYRA_BUILDDATE@\""\ -DHYRA_ARCH="\"@ARCH@\"" $(shell cat sys/arch/$(ARCH)/conf/GENERIC | tools/kconf/kconf) ###################### -# Initramfs config -###################### -override RAMFS_TOOL = @RAMFS_TOOL@ -override RAMFS_LOC = ramfs.omar - -###################### # Toolchain ###################### override TOOLCHAIN = @TOOLCHAIN@ @@ -70,10 +65,10 @@ override SBIN_MAKEDIRS = $(shell find usr.sbin/ -type d -name "*" | awk '!/usr.s override BIN_MAKEDIRS = $(shell find usr.bin/ -type d -name "*" | awk '!/usr.bin\/$$/') override USRDIR = $(shell pwd)/base/usr + .PHONY: all -all: base libc sbin bin base/boot/hyra-kernel ramfs iso +all: stand/boot/ libc sbin bin base/boot/hyra-kernel rm -f sys/include/machine - rm -rf iso_root .PHONY: sbin sbin: $(SBIN_MAKEDIRS) @@ -90,15 +85,6 @@ libc: $(MAKE) -C lib/libc/ -I$(shell pwd)/builddeps \ USRDIR=$(USRDIR) ARCH=$(ARCH) ROOT=$(PROJECT_ROOT) -.PHONY: base -base: - mkdir -p base/usr/lib/ - mkdir -p base/usr/sbin/ - mkdir -p base/usr/bin/ - mkdir -p base/boot/ - mkdir -p base/usr/include/sys/ - cp -f sys/include/sys/*.h base/usr/include/sys/ - .PHONY: cross cross: bash tools/cross.sh $(ARCH) @@ -107,34 +93,16 @@ cross: run: $(QEMU) $(QEMU_FLAGS) -.PHONY: ramfs -ramfs: - $(RAMFS_TOOL) -i base/ -o ramfs.omar - $(PROMPT) " RAMFS " $(shell pwd)/ramfs.omar - .PHONY: clean clean: rm -f $(KERNEL_ASMOBJECTS) $(KERNEL_OBJECTS) $(KERNEL_HEADER_DEPS) rm -f sys/include/machine -.PHONY: iso -iso: - mkdir -p iso_root/boot/ - mkdir -p iso_root/EFI/BOOT/ - cp stand/limine/$(BOOT_FW) iso_root/EFI/BOOT/ - mv $(RAMFS_LOC) iso_root/boot/ - cp builddeps/limine.conf stand/limine/limine-bios.sys \ - stand/limine/limine-bios-cd.bin stand/limine/limine-uefi-cd.bin iso_root/ - cp base/boot/* iso_root/boot/ - cp builddeps/tree.jpg iso_root/boot/ - xorriso -as mkisofs -b limine-bios-cd.bin -no-emul-boot -boot-load-size 4\ - -boot-info-table --efi-boot limine-uefi-cd.bin -efi-boot-part \ - --efi-boot-image --protective-msdos-label iso_root -o Hyra.iso > /dev/null - stand/limine/limine bios-install Hyra.iso - $(PROMPT) " ISO " $(shell pwd)/Hyra.iso +stand/boot/: + mkdir -p stand/boot/ + cp stand/limine/$(BOOT_FW) stand/boot/ base/boot/hyra-kernel: $(KERNEL_OBJECTS) $(KERNEL_ASMOBJECTS) - rm -rf iso_root $(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 @@ -17,16 +17,15 @@ Next, to configure for x86_64 just run configure: `./configure` -Now you'll need to build the cross compiler by running: +After running the configure script, you can now actually build Hyra: -`make cross` +`./hyra-build.sh` -This may take awhile so just sit back, relax and do something else like... well I'm not you so -I don't know what you like. +This will create two ISO files: -After the cross compiler is done building you can build and run the project in a virtual machine: +`Hyra.iso Hyra-install.iso` -`make; make run` +As of now, you should ignore the second file (`Hyra-install.iso`) Documentation: -------------- diff --git a/configure.ac b/configure.ac index 7d0f5fa..5c19c32 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([Hyra], [1.6], [ian@osmora.org]) +AC_INIT([Hyra], [1.7], [ian@osmora.org]) TARGET="amd64" PROJECT_ROOT=`pwd` @@ -59,6 +59,5 @@ AC_SUBST(BOOT_FW, [$BOOT_FW]) AC_SUBST(ARCH, [$TARGET]) AC_SUBST(PROJECT_ROOT, [$PROJECT_ROOT]) AC_SUBST(TOOLCHAIN, [clang]) -AC_SUBST(RAMFS_TOOL, [tools/omar/bin/omar]) AC_CONFIG_FILES([Makefile]) AC_OUTPUT diff --git a/hyra-build.sh b/hyra-build.sh new file mode 100755 index 0000000..4766261 --- /dev/null +++ b/hyra-build.sh @@ -0,0 +1,174 @@ +#!/bin/bash + +# +# Copyright (c) 2023-2025 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. +# + +set -e + +RAMFS_TOOL="tools/omar/bin/omar" +RAMFS_NAME="ramfs.omar" +install_flag="false" + +############################### +# Generate sysroot skeleton +############################### +sysroot_skel() { + mkdir -p base/usr/lib/ + mkdir -p base/usr/sbin/ + mkdir -p base/usr/bin/ + mkdir -p base/boot/ + mkdir -p base/usr/include/sys/ + cp -f sys/include/sys/*.h base/usr/include/sys + + # Populate ESP + make stand/boot/ + cp stand/boot/*.EFI iso_root/EFI/BOOT/ +} + +iso_root_skel() { + mkdir -p iso_root/boot/ + mkdir -p iso_root/EFI/BOOT/ +} + +############################### +# Generate ISO root +############################### +gen_iso_root() { + cp $RAMFS_NAME iso_root/boot/ + cp builddeps/limine.conf stand/limine/limine-bios.sys \ + stand/limine/limine-bios-cd.bin stand/limine/limine-uefi-cd.bin iso_root/ + cp builddeps/tree.jpg iso_root/boot/ +} + +################################## +# Stage 1 - generate isofs +# +# ++ ARGS ++ +# $1: ISO output name +# -- -- +################################## +gen_isofs() { + cp base/boot/* iso_root/boot/ + xorriso -as mkisofs -b limine-bios-cd.bin -no-emul-boot -boot-load-size 4\ + -boot-info-table --efi-boot limine-uefi-cd.bin -efi-boot-part \ + --efi-boot-image --protective-msdos-label iso_root -o $1 > /dev/null + stand/limine/limine bios-install $1 +} + +#################################### +# Stage 1 - build production media +#################################### +stage1() { + iso_root_skel + sysroot_skel + + echo "[*] stage1: Generate stage 1 RAMFS via OMAR" + $RAMFS_TOOL -i base/ -o $RAMFS_NAME + + echo "[*] stage1: Build kernel" + gen_iso_root + make KBUILD_ARGS="-D_INSTALL_MEDIA=0" + + echo "[*] stage1: Generate stage 1 ISOFS (production)" + gen_isofs "Hyra.iso" + + # Clean up + rm $RAMFS_NAME + rm -r iso_root +} + +################################# +# Stage 2 - build install media +################################# +stage2() { + make clean + rm -f base/boot/hyra-kernel + + iso_root_skel + sysroot_skel + + echo "[*] stage2: Generate stage 2 RAMFS via OMAR" + $RAMFS_TOOL -i base/ -o $RAMFS_NAME + + echo "[*] stage2: Build kernel" + gen_iso_root + make KBUILD_ARGS="-D_INSTALL_MEDIA=1" + + echo "[*] stage2: Generate stage 2 ISOFS (installer)" + gen_isofs "Hyra-install.iso" + + # Clean up + rm $RAMFS_NAME + rm -r iso_root +} + +while getopts "ih" flag +do + case "${flag}" in + i) install_flag="true" + ;; + *) + echo "Hyra build script" + echo "[-i] Build installer" + echo "[-h] Help" + exit 1 + ;; + esac +done + +if [[ ! -f ./configure ]] +then + echo "[!] Please bootstrap and configure Hyra!" + echo "[!] Error in stage 1, exiting" + exit 1 +fi + +if [[ ! -f Makefile ]] +then + echo "[!] 'Makefile' not found, did you run './configure'?" + echo "[!] Error in stage 1, exiting" +fi + +echo "-- Begin stage 1 --" +stage1 + +if [[ $install_flag != "true" ]] +then + echo "[?] Not building installer (-i unset)" + echo "-- Skipping stage 2 --" +else + echo "-- Begin stage 2 --" + stage2 +fi + +echo "-------------------------------------------" +echo "Build finish" +echo "Installer is at ./Hyra-install.iso" +echo "Finished in $(($SECONDS / 60)) minutes and $(($SECONDS % 60)) seconds" +echo "-------------------------------------------" diff --git a/sys/dev/cons/cons.c b/sys/dev/cons/cons.c index b89727f..bcd19bf 100644 --- a/sys/dev/cons/cons.c +++ b/sys/dev/cons/cons.c @@ -91,9 +91,9 @@ cons_draw_char(struct cons_screen *scr, struct cons_char ch) y = ch.y; for (uint32_t cy = 0; cy < FONT_HEIGHT; ++cy) { + idx = fbdev_get_index(&scr->fbdev, x + (FONT_WIDTH - 1), y + cy); for (uint32_t cx = 0; cx < FONT_WIDTH; ++cx) { - idx = fbdev_get_index(&scr->fbdev, x + (FONT_WIDTH - 1) - cx, y + cy); - scr->fb_mem[idx] = ISSET(glyph[cy], BIT(cx)) ? ch.fg : ch.bg; + scr->fb_mem[idx--] = ISSET(glyph[cy], BIT(cx)) ? ch.fg : ch.bg; } } } @@ -221,9 +221,9 @@ cons_draw_cursor(struct cons_screen *scr, uint32_t color) } for (uint32_t cy = 0; cy < FONT_HEIGHT; ++cy) { + idx = fbdev_get_index(&scr->fbdev, scr->curs_col * FONT_WIDTH, (scr->curs_row * FONT_HEIGHT) + cy); for (uint32_t cx = 0; cx < FONT_WIDTH; ++cx) { - idx = fbdev_get_index(&scr->fbdev, (scr->curs_col * FONT_WIDTH) + cx, (scr->curs_row * FONT_HEIGHT) + cy); - scr->fb_mem[idx] = color; + scr->fb_mem[idx++] = color; } } } @@ -249,19 +249,57 @@ cons_clear_scr(struct cons_screen *scr, uint32_t bg) } /* - * Character device function. + * Quickly put a character on the screen. + * XXX: Does not acquire the screen's lock or show/hide the cursor. + * + * @scr: Screen. + * @c: Character to draw. */ -static int -dev_write(dev_t dev, struct sio_txn *sio, int flags) +static void +cons_fast_putch(struct cons_screen *scr, char c) { - char *p; + struct cons_char cc; + struct cons_buf *bp; + + /* Handle specials */ + if (cons_handle_special(scr, c) == 0) { + return; + } + + /* Create a new character */ + cc.c = c; + cc.fg = scr->fg; + cc.bg = scr->bg; + cc.x = scr->ch_col * FONT_WIDTH; + cc.y = scr->ch_row * FONT_HEIGHT; - p = sio->buf; + /* Push our new character */ + bp = scr->ob[scr->ch_row]; + bp->flags &= ~CONS_BUF_CLEAN; + cons_obuf_push(bp, cc); + ++scr->ch_col; - for (size_t i = 0; i < sio->len; ++i) { - cons_putch(&g_root_scr, p[i]); + /* Check screen bounds */ + if (cc.x >= (scr->ncols * FONT_WIDTH) - 1) { + scr->ch_col = 0; + ++scr->ch_row; } + ++scr->curs_col; + if (scr->curs_col > scr->ncols - 1) { + scr->curs_col = 0; + if (scr->curs_row < scr->nrows) + ++scr->curs_row; + } +} + +/* + * Character device function. + */ +static int +dev_write(dev_t dev, struct sio_txn *sio, int flags) +{ + cons_putstr(&g_root_scr, sio->buf, sio->len); cons_flush(&g_root_scr); return sio->len; } @@ -347,47 +385,37 @@ cons_init_bufs(struct cons_screen *scr) int cons_putch(struct cons_screen *scr, char c) { - struct cons_buf *bp; - struct cons_char cc; - size_t max_width; - spinlock_acquire(&scr->lock); + HIDE_CURSOR(scr); - /* Handle specials */ - if (cons_handle_special(scr, c) == 0) { - goto done; - } + cons_fast_putch(scr, c); - HIDE_CURSOR(scr); + SHOW_CURSOR(scr); + spinlock_release(&scr->lock); + return 0; +} - /* Create a new character */ - cc.c = c; - cc.fg = scr->fg; - cc.bg = scr->bg; - cc.x = scr->ch_col * FONT_WIDTH; - cc.y = scr->ch_row * FONT_HEIGHT; +/* + * Put a string on the screen. + * + * @scr: Screen. + * @s: String to draw. + * @l: Length of s. + */ +int +cons_putstr(struct cons_screen *scr, const char *s, size_t len) +{ + const char *p = s; - /* Push our new character */ - bp = scr->ob[scr->ch_row]; - bp->flags &= ~CONS_BUF_CLEAN; - cons_obuf_push(bp, cc); - ++scr->ch_col; + spinlock_acquire(&scr->lock); + HIDE_CURSOR(scr); - /* Check screen bounds */ - max_width = scr->ncols * FONT_WIDTH; - if (cc.x >= max_width - 1) { - scr->ch_col = 0; - ++scr->ch_row; + while (len--) { + cons_fast_putch(scr, *p); + ++p; } - ++scr->curs_col; - if (scr->curs_col > scr->ncols - 1) { - scr->curs_col = 0; - if (scr->curs_row < scr->nrows) - ++scr->curs_row; - } SHOW_CURSOR(scr); -done: spinlock_release(&scr->lock); return 0; } diff --git a/sys/include/dev/cons/cons.h b/sys/include/dev/cons/cons.h index 3569c52..b27be23 100644 --- a/sys/include/dev/cons/cons.h +++ b/sys/include/dev/cons/cons.h @@ -65,6 +65,7 @@ struct cons_screen { void cons_init(void); void cons_expose(void); int cons_putch(struct cons_screen *scr, char c); +int cons_putstr(struct cons_screen *scr, const char *s, size_t len); extern struct cons_screen g_root_scr; diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 5845c1c..bfafaf1 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -84,6 +84,11 @@ main(void) kprintf("Starting Hyra/%s v%s: %s\n", HYRA_ARCH, HYRA_VERSION, HYRA_BUILDDATE); +#if _INSTALL_MEDIA + kprintf("Hyra install media detected\n"); + kprintf("Reform Industry!\n"); +#endif /* _INSTALL_MEDIA */ + /* Start the ACPI subsystem */ acpi_init(); diff --git a/sys/kern/kern_syslog.c b/sys/kern/kern_syslog.c index 665734d..656362e 100644 --- a/sys/kern/kern_syslog.c +++ b/sys/kern/kern_syslog.c @@ -46,15 +46,19 @@ static struct spinlock lock = {0}; static void syslog_write(const char *s, size_t len) { - const char *p = s; + const char *p; + size_t l; - while (len--) { - cons_putch(&g_root_scr, *p); - if (SERIAL_DEBUG) { + if (SERIAL_DEBUG) { + p = s; + l = len; + while (l--) { serial_putc(*p); + ++p; } - ++p; } + + cons_putstr(&g_root_scr, s, len); } /* |