From 0ace22d6f88692883584119c64ff010f4cee6738 Mon Sep 17 00:00:00 2001 From: salmonik Date: Fri, 31 Jul 2026 03:22:20 +0200 Subject: fix(rsdos): organizational changes --- .gitignore | 1 + .gitmodules | 3 ++ CONTEXT.md | 2 +- Makefile | 56 ++++++++++++++----------- rsboot | 1 + rsnix/src/interrupts.rs | 2 +- rsnix/src/lib.rs | 8 ++-- rsnix/src/ps2.rs | 7 ++-- scripts/boot-image.sh | 87 ++++++++++++++++++++++++++++++++++++++ scripts/boot.sh | 100 ++++++++++++++++++++++++++++++++++++++++++++ scripts/build-bootloader.sh | 32 ++++++++++++++ scripts/build-image.sh | 99 +++++++++++++++++++++++++++++++++++++++++++ scripts/debug-kernel.py | 64 ++++++++++++++++++++++++++++ scripts/qemu.sh | 96 ++++++++++++++++++++++++++++++++++++++++++ tools/boot-image.sh | 62 --------------------------- tools/debug-kernel.py | 64 ---------------------------- tools/qemu.sh | 96 ------------------------------------------ 17 files changed, 523 insertions(+), 257 deletions(-) create mode 100644 .gitmodules create mode 160000 rsboot create mode 100755 scripts/boot-image.sh create mode 100755 scripts/boot.sh create mode 100755 scripts/build-bootloader.sh create mode 100755 scripts/build-image.sh create mode 100755 scripts/debug-kernel.py create mode 100755 scripts/qemu.sh delete mode 100755 tools/boot-image.sh delete mode 100755 tools/debug-kernel.py delete mode 100755 tools/qemu.sh diff --git a/.gitignore b/.gitignore index 2353fdc..42b56cf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /target +/build /esp/ *.img NvVars diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..423167d --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "rsboot"] + path = rsboot + url = https://git.2137697.xyz/RaiserSoft/rsboot.git diff --git a/CONTEXT.md b/CONTEXT.md index 283467a..c1c5781 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -87,7 +87,7 @@ Single Rust crate (`x86_64-unknown-uefi` target). Module breakdown: ## Milestone status (v0.1) -✅ **Booting** — kernel loads via rsbl, prints banner via UEFI console +✅ **Booting** — kernel loads via rsbl, prints banner via UEFI console (verified on real hardware) ✅ **ExitBootServices** — memory map captured via static `.bss` buffer (see `docs/adr/0001-static-buffer-for-memory-map.md`) ✅ **Serial** — UART 16550 at COM1, 115200 8N1 diff --git a/Makefile b/Makefile index 1fc4194..1d60062 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ export BOOTLOADER=rsboot/rsboot.efi export OVMF=/usr/share/edk2/x64/OVMF.4m.fd export BOOT_EFI=$(ESP_DIR)/EFI/BOOT/BOOTX64.EFI -.PHONY: all run run-gui clean image debug release fmt +.PHONY: all run run-gui clean image debug release fmt bootloader boot-image # ---- Build --------------------------------------------------------------- @@ -75,23 +75,24 @@ debug: all -display none \ -s -S -# Boot from a raw disk image (created by tools/boot-image.sh) +# Boot from a raw disk image (delegates to boot-image.sh which builds the +# full chain if the image doesn't exist yet) run-image: all - qemu-system-x86_64 \ - -bios $(OVMF) \ - -drive file=$(IMG),format=raw,if=none,id=hd \ - -device ide-hd,drive=hd \ - -serial stdio \ - -m 256M \ - -machine q35 \ - -cpu qemu64 \ - -no-reboot \ - -display none + ./scripts/boot-image.sh rs-dos.img -# ---- Disk image ---------------------------------------------------------- +# ---- Full boot chain ----------------------------------------------------- +# Build bootloader only (rsboot submodule) +bootloader: + ./scripts/build-bootloader.sh + +# Build the full boot chain disk image (kernel + bootloader) image: all - ./tools/boot-image.sh rs-dos.img + ./scripts/build-image.sh rs-dos.img + +# Boot the full chain disk image (builds it first if needed) +boot-image: all + ./scripts/boot-image.sh rs-dos.img # ---- Utilities ----------------------------------------------------------- @@ -105,16 +106,21 @@ clean: help: @echo "rs-dos — Make targets" @echo "" - @echo " make build kernel + ESP (default)" - @echo " make release build with --release (smaller binary)" - @echo " make image create bootable USB image (rs-dos.img)" - @echo " make run QEMU serial console (no graphics)" - @echo " make run-gui QEMU with graphical window (GOP/PS2)" - @echo " make debug QEMU + GDB stub on :1234" - @echo " make clean remove build artifacts" - @echo " make fmt format Rust source" + @echo " make build kernel + ESP (default)" + @echo " make release build with --release (smaller binary)" + @echo " make bootloader build rsboot from source" + @echo " make image build full chain disk image (bootloader + kernel)" + @echo " make boot-image build + boot full chain via QEMU" + @echo " make run QEMU serial console (direct boot, no bootloader)" + @echo " make run-gui QEMU with graphical window (GOP/PS2)" + @echo " make debug QEMU + GDB stub on :1234" + @echo " make clean remove build artifacts" + @echo " make fmt format Rust source" @echo "" @echo "Scripts:" - @echo " ./tools/qemu.sh flexible QEMU launcher" - @echo " ./tools/boot-image.sh create bootable disk image" - @echo " ./tools/debug-kernel.py GDB plugin (attach after 'make debug')" + @echo " ./scripts/boot.sh quick direct boot (dev loop)" + @echo " ./scripts/boot-image.sh boot full chain (builds if needed)" + @echo " ./scripts/build-image.sh build full chain disk image" + @echo " ./scripts/build-bootloader.sh build rsboot from source" + @echo " ./scripts/qemu.sh flexible QEMU launcher" + @echo " ./scripts/debug-kernel.py GDB plugin (attach after 'make debug')" diff --git a/rsboot b/rsboot new file mode 160000 index 0000000..1963a0a --- /dev/null +++ b/rsboot @@ -0,0 +1 @@ +Subproject commit 1963a0a6d7398a426d0701f90a5bc796e32899ae diff --git a/rsnix/src/interrupts.rs b/rsnix/src/interrupts.rs index 8f2acd7..66dc59f 100644 --- a/rsnix/src/interrupts.rs +++ b/rsnix/src/interrupts.rs @@ -362,7 +362,7 @@ pub fn init() { // Build the IDTR pseudo-descriptor. IDTR = [ - ((256u16 * 16 - 1)), // limit = 256*16 - 1 + (256u16 * 16 - 1), // limit = 256*16 - 1 idt_ptr as u16, // base lo (idt_ptr as u64 >> 16) as u16, // base mid (idt_ptr as u64 >> 32) as u16, // base hi diff --git a/rsnix/src/lib.rs b/rsnix/src/lib.rs index 6c7fb3c..0bc0cb9 100644 --- a/rsnix/src/lib.rs +++ b/rsnix/src/lib.rs @@ -2,10 +2,10 @@ extern crate alloc; -pub mod uefi; -pub mod serial; -pub mod gop; pub mod font; -pub mod ps2; +pub mod gop; pub mod interrupts; pub mod memory; +pub mod ps2; +pub mod serial; +pub mod uefi; diff --git a/rsnix/src/ps2.rs b/rsnix/src/ps2.rs index b83a4e0..477d146 100644 --- a/rsnix/src/ps2.rs +++ b/rsnix/src/ps2.rs @@ -346,10 +346,9 @@ fn update_modifiers(scancode: u8, pressed: bool, e0: bool) { (0x1D, true) => set_mod(state, MOD_RCTRL, pressed), (0x38, false) => set_mod(state, MOD_LALT, pressed), (0x38, true) => set_mod(state, MOD_RALT, pressed), - (0x3A, false) - if pressed => { - state.modifiers ^= MOD_CAPS; - } + (0x3A, false) if pressed => { + state.modifiers ^= MOD_CAPS; + } _ => {} } } diff --git a/scripts/boot-image.sh b/scripts/boot-image.sh new file mode 100755 index 0000000..913e5cb --- /dev/null +++ b/scripts/boot-image.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash +# +# scripts/boot-image.sh — boot rs-dos full chain disk image in QEMU +# +# Builds the image first if needed, then boots with UEFI firmware through +# the real boot chain: firmware → rsboot → rsnix kernel. +# +# Usage: +# ./scripts/boot-image.sh [--gui] [--debug] [--mem 512M] [--smp 2] +# +# Keybindings: +# Ctrl-A X — quit +# Ctrl-A C — QEMU monitor +# +# Environment: +# OVMF path to OVMF firmware (default: /usr/share/edk2/x64/OVMF.4m.fd) +# MEM memory size (default: 256M) +# SMP CPU count (default: 1) +# +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PROJECT_DIR="$(dirname "$SCRIPT_DIR")" + +cd "$PROJECT_DIR" + +IMAGE="rs-dos.img" + +# ---- config ---- +OVMF="${OVMF:-/usr/share/edk2/x64/OVMF.4m.fd}" +MEM="${MEM:-256M}" +SMP="${SMP:-1}" +GUI="" +DEBUG="" + +# ---- args ---- +while [ $# -gt 0 ]; do + case "$1" in + --gui | -g) GUI="-vga std" ;; + --debug | -d) DEBUG="-s -S" ;; + --mem) + shift + MEM="$1" + ;; + --smp) + shift + SMP="$1" + ;; + --help | -h) + head -20 "$0" | grep "^#" | sed 's/^# //' + exit 0 + ;; + *) + echo "unknown: $1" + exit 1 + ;; + esac + shift +done + +# ---- build image if missing ---- +if [ ! -f "$IMAGE" ]; then + echo "Image not found, building..." + "$SCRIPT_DIR/build-image.sh" +fi + +# ---- boot ---- +echo "" +echo "=== Booting (full chain: firmware → rsboot → rsnix) ===" +echo " image: $IMAGE" +echo " ovmf: $OVMF" +echo " mem: $MEM smp: $SMP" +echo " gui: $([ -n "$GUI" ] && echo yes || echo no)" +echo " gdb: $([ -n "$DEBUG" ] && echo ':1234' || echo off)" +echo "" + +exec qemu-system-x86_64 \ + -bios "$OVMF" \ + -drive file="$IMAGE",format=raw,if=none,id=hd \ + -device ide-hd,drive=hd \ + -serial stdio \ + -m "$MEM" \ + -machine q35 \ + -cpu qemu64 \ + -no-reboot \ + -smp "$SMP" \ + $GUI $DEBUG diff --git a/scripts/boot.sh b/scripts/boot.sh new file mode 100755 index 0000000..1e3f739 --- /dev/null +++ b/scripts/boot.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env bash +# +# scripts/boot.sh — quick direct boot in QEMU (dev loop) +# +# Fastest iteration: boots the kernel directly as BOOTX64.EFI via QEMU's +# FAT driver, skipping the bootloader entirely. +# +# Usage: +# ./scripts/boot.sh [--gui] [--debug] [--release] [--mem 512M] [--smp 2] +# +# Boot chain: firmware → rsnix (direct) +# Full chain: use ./scripts/boot-image.sh (firmware → rsboot → rsnix) +# +# Keybindings: +# Ctrl-A X — quit +# Ctrl-A C — QEMU monitor +# +# Environment: +# OVMF path to OVMF firmware (default: /usr/share/edk2/x64/OVMF.4m.fd) +# MEM memory size (default: 256M) +# SMP CPU count (default: 1) +# +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PROJECT_DIR="$(dirname "$SCRIPT_DIR")" + +cd "$PROJECT_DIR" + +ESP_DIR="$PROJECT_DIR/esp" + +# ---- config ---- +OVMF="${OVMF:-/usr/share/edk2/x64/OVMF.4m.fd}" +MEM="${MEM:-256M}" +SMP="${SMP:-1}" +PROFILE="debug" +CARGO_FLAGS="" +GUI="" +DEBUG="" + +# ---- args ---- +while [ $# -gt 0 ]; do + case "$1" in + --gui | -g) GUI="-vga std" ;; + --debug | -d) DEBUG="-s -S" ;; + --release | -r) + PROFILE="release" + CARGO_FLAGS="--release" + ;; + --mem) + shift + MEM="$1" + ;; + --smp) + shift + SMP="$1" + ;; + --help | -h) + head -20 "$0" | grep "^#" | sed 's/^# //' + exit 0 + ;; + *) + echo "unknown: $1" + exit 1 + ;; + esac + shift +done + +OUT_DIR="target/x86_64-unknown-uefi/$PROFILE" +KERNEL="$OUT_DIR/rsdos.efi" + +# ---- build ---- +echo "=== Building kernel ($PROFILE) ===" +cargo build --package rsdos --target x86_64-unknown-uefi $CARGO_FLAGS + +# ---- deploy ---- +mkdir -p "$ESP_DIR/EFI/BOOT" +cp "$KERNEL" "$ESP_DIR/EFI/BOOT/BOOTX64.EFI" +echo " kernel: $(ls -lh "$KERNEL" | awk '{print $5}')" + +# ---- boot ---- +echo "" +echo "=== Booting (direct: firmware → rsnix) ===" +echo " ovmf: $OVMF" +echo " mem: $MEM smp: $SMP" +echo " gui: $([ -n "$GUI" ] && echo yes || echo no)" +echo " gdb: $([ -n "$DEBUG" ] && echo ':1234' || echo off)" +echo "" + +exec qemu-system-x86_64 \ + -bios "$OVMF" \ + -drive file=fat:rw:"$ESP_DIR",format=raw \ + -serial stdio \ + -m "$MEM" \ + -machine q35 \ + -cpu qemu64 \ + -no-reboot \ + -smp "$SMP" \ + $GUI $DEBUG diff --git a/scripts/build-bootloader.sh b/scripts/build-bootloader.sh new file mode 100755 index 0000000..9a96cfe --- /dev/null +++ b/scripts/build-bootloader.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +# +# scripts/build-bootloader.sh — build rsboot (UEFI bootloader) +# +# rsboot is a git submodule at rsboot/. This builds it and places +# BOOTX64.EFI into build/bootloader/. +# +# Usage: +# ./scripts/build-bootloader.sh +# +# Output: +# build/bootloader/BOOTX64.EFI +# +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PROJECT_DIR="$(dirname "$SCRIPT_DIR")" +BUILD_DIR="$PROJECT_DIR/build" +BOOTLOADER_DIR="$BUILD_DIR/bootloader" + +echo "=== Building rsboot (UEFI bootloader) ===" + +# Ensure submodule is checked out +git submodule update --init "$PROJECT_DIR/rsboot" + +cd "$PROJECT_DIR/rsboot" +make clean 2>/dev/null || true +make -j"$(nproc)" 2>&1 | sed 's/^/ /' + +echo "" +echo "=== rsboot build complete ===" +ls -lh "$BOOTLOADER_DIR/BOOTX64.EFI" diff --git a/scripts/build-image.sh b/scripts/build-image.sh new file mode 100755 index 0000000..02672ad --- /dev/null +++ b/scripts/build-image.sh @@ -0,0 +1,99 @@ +#!/usr/bin/env bash +# +# scripts/build-image.sh — assemble a bootable rs-dos disk image (UEFI/GPT) +# +# Layout: +# Partition 1: ESP (FAT32) — rsboot bootloader + kernel +# +# Output: +# rs-dos.img (or custom path) — bootable raw disk image for UEFI +# +# Usage: +# ./scripts/build-image.sh [output.img] +# +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PROJECT_DIR="$(dirname "$SCRIPT_DIR")" + +cd "$PROJECT_DIR" + +BUILD_DIR="$PROJECT_DIR/build" +ESP_DIR="$PROJECT_DIR/esp" + +IMAGE="${1:-$PROJECT_DIR/rs-dos.img}" +TARGET=x86_64-unknown-uefi +PROFILE=debug +OUT_DIR="target/${TARGET}/${PROFILE}" + +BOOTLOADER="$BUILD_DIR/bootloader/BOOTX64.EFI" +KERNEL="$OUT_DIR/rsdos.efi" +BZIMAGE="$ESP_DIR/bzImage" +INITRD="$ESP_DIR/initramfs.cpio.gz" +BOOT_EFI="$ESP_DIR/EFI/BOOT/BOOTX64.EFI" + +ESP_START=2048 # 1 MiB offset (standard alignment) +ESP_SIZE_MB=64 + +IMAGE_SIZE_MB=$((ESP_SIZE_MB + 2)) # ESP + GPT gap + backup + +# ---- checks ---- +for cmd in sfdisk mkfs.vfat mcopy truncate dd; do + if ! command -v "$cmd" &>/dev/null; then + echo "Error: $cmd not found" + exit 1 + fi +done + +# ---- build kernel ---- +echo "[1/4] Building kernel..." +cargo build --package rsdos --target x86_64-unknown-uefi ${CARGO_FLAGS:-} + +# ---- build bootloader ---- +echo "[2/4] Building bootloader..." +if [ ! -f "$BOOTLOADER" ]; then + "$SCRIPT_DIR/build-bootloader.sh" +fi + +# ---- assemble ESP ---- +echo "[3/4] Assembling ESP..." +mkdir -p "$ESP_DIR/EFI/BOOT" +cp "$KERNEL" "$BZIMAGE" +cp "$BOOTLOADER" "$BOOT_EFI" +if [ ! -f "$INITRD" ]; then + printf '' | gzip >"$INITRD" +fi + +# ---- create disk image ---- +echo "[4/4] Writing disk image..." +rm -f "$IMAGE" +truncate -s "${IMAGE_SIZE_MB}M" "$IMAGE" + +# GPT partition table: single EFI System partition +sfdisk --quiet "$IMAGE" </dev/null 2>&1 + +# Copy files into FAT +mmd -i "$ESP_IMG" ::/EFI 2>/dev/null || true +mmd -i "$ESP_IMG" ::/EFI/BOOT 2>/dev/null || true +mcopy -i "$ESP_IMG" "$BOOT_EFI" ::/EFI/BOOT/BOOTX64.EFI +mcopy -i "$ESP_IMG" "$BZIMAGE" ::/bzImage 2>/dev/null || true +mcopy -i "$ESP_IMG" "$INITRD" ::/initramfs.cpio.gz 2>/dev/null || true + +# Inject FAT into image at partition offset +dd if="$ESP_IMG" of="$IMAGE" bs=512 seek="$ESP_START" conv=notrunc 2>/dev/null +rm -f "$ESP_IMG" + +echo "" +echo "=== Done: $IMAGE ===" +ls -lh "$IMAGE" +echo "" +echo "Boot with: ./scripts/boot-image.sh" +echo "USB: sudo dd if=$IMAGE of=/dev/sdX bs=4M status=progress" diff --git a/scripts/debug-kernel.py b/scripts/debug-kernel.py new file mode 100755 index 0000000..c794ad6 --- /dev/null +++ b/scripts/debug-kernel.py @@ -0,0 +1,64 @@ +""" +GDB Python script for debugging raisernics under QEMU. + +Usage: + 1. Terminal 1: ./tools/qemu.sh --debug + 2. Terminal 2: gdb -x tools/debug-kernel.py target/x86_64-unknown-uefi/debug/raisernics.efi +""" + +import gdb +import os + +# Find the kernel binary +script_dir = os.path.dirname(os.path.abspath(__file__)) +project_root = os.path.dirname(script_dir) +binary = os.path.join( + project_root, + "target/x86_64-unknown-uefi/debug/raisernics.efi" +) + +# Connect to QEMU's GDB stub +gdb.execute("target remote :1234") + +# Load the binary (add symbol table) +if os.path.exists(binary): + gdb.execute(f"symbol-file {binary}") + print(f"Loaded symbols from {binary}") +else: + print(f"WARNING: {binary} not found. Build with debug symbols first.") + +gdb.execute("set breakpoint pending on") + + +# Helper commands +class DumpBootServices(gdb.Command): + """Dump EFI boot services signature and key pointers""" + + def __init__(self): + super().__init__("dump-bs", gdb.COMMAND_USER) + + def invoke(self, argument, from_tty): + del argument, from_tty + gdb.execute("printf \"SystemTable, BootServices, and key function pointers\\n\"") + gdb.execute("info functions efi_main") + + +class DumpGop(gdb.Command): + """Dump GOP framebuffer info""" + + def __init__(self): + super().__init__("dump-gop", gdb.COMMAND_USER) + + def invoke(self, argument, from_tty): + del argument, from_tty + gdb.execute("printf \"Check the gop::Framebuffer static\\n\"") + + +DumpBootServices() +DumpGop() + +print("") +print("raisernics GDB session ready.") +print(" target remote :1234 (connected)") +print(" Commands: continue, stepi, bt, info registers, etc.") +print(" Custom: dump-bs, dump-gop") diff --git a/scripts/qemu.sh b/scripts/qemu.sh new file mode 100755 index 0000000..b75bed4 --- /dev/null +++ b/scripts/qemu.sh @@ -0,0 +1,96 @@ +#!/usr/bin/env bash +# ============================================================================= +# tools/qemu.sh — Run raisernics in QEMU with various options +# +# Usage: +# ./tools/qemu.sh # serial console (no graphics) +# ./tools/qemu.sh --gui # graphical window +# ./tools/qemu.sh --debug # GDB stub on :1234 +# ./tools/qemu.sh --image foo.img # boot from raw disk image +# ./tools/qemu.sh --bios /path/to.fd # custom OVMF +# ./tools/qemu.sh --mem 512M # memory size +# ./tools/qemu.sh --smp 2 # SMP cores +# ============================================================================= +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)" +cd "$SCRIPT_DIR" + +# Defaults +GUI_FLAG="" +DEBUG_FLAG="" +DRIVE_ARGS=(-drive file=fat:rw:esp,format=raw) +OVMF="${OVMF:-/usr/share/edk2/x64/OVMF.4m.fd}" +MEM="${MEM:-256M}" +SMP="${SMP:-1}" + +# Pre-build +make all + +# Parse args +while [ $# -gt 0 ]; do + case "$1" in + --gui | -g) + GUI_FLAG="-vga std" + shift + ;; + --debug | -d) + DEBUG_FLAG="-s -S" + shift + ;; + --image | -i) + _img_file="$(printf -- '-drive file=%s,format=raw,if=none,id=hd' "$2")" + DRIVE_ARGS=("$_img_file" '-device' 'ide-hd,drive=hd') + shift 2 + ;; + --bios | -b) + OVMF="$2" + shift 2 + ;; + --mem) + MEM="$2" + shift 2 + ;; + --smp) + SMP="$2" + shift 2 + ;; + --help | -h) + head -20 "$0" | grep "^# " | sed 's/^# //' + exit 0 + ;; + *) + echo "Unknown option: $1" + exit 1 + ;; + esac +done + +QEMU_CMD=( + qemu-system-x86_64 + -bios "$OVMF" + "${DRIVE_ARGS[@]}" + -serial stdio + -m "$MEM" + -machine q35 + -cpu qemu64 + -no-reboot + -smp "$SMP" +) + +[ -n "$GUI_FLAG" ] && QEMU_CMD+=("$GUI_FLAG") +if [ -n "$DEBUG_FLAG" ]; then + # Split the flag string safely into words + read -ra dbg <<<"$DEBUG_FLAG" + QEMU_CMD+=("${dbg[@]}") +fi + +echo " OVMF : $OVMF" +echo " Drive : ${DRIVE_ARGS[*]}" +echo " Mem : $MEM" +echo " SMP : $SMP" +echo " GDB : $([ -n "$DEBUG_FLAG" ] && echo ':1234' || echo 'off')" +echo " GUI : $([ -n "$GUI_FLAG" ] && echo 'yes' || echo 'no')" +echo "" + +exec "${QEMU_CMD[@]}" diff --git a/tools/boot-image.sh b/tools/boot-image.sh deleted file mode 100755 index 2592afa..0000000 --- a/tools/boot-image.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env bash -# ============================================================================= -# tools/boot-image.sh — Create a bootable disk image from the ESP directory -# -# Produces a raw disk image (bootable via UEFI) for dd-ing to a USB stick -# or attaching to QEMU as a hard disk. -# -# Usage: -# ./tools/boot-image.sh [output.img] -# -# Default output: raisernics.img -# ============================================================================= -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)" -cd "$SCRIPT_DIR" - -OUTPUT="${1:-raisernics.img}" -ESP_DIR="${ESP_DIR:-esp}" -MBR_SZ=1 # 1 MB reserved at start for GPT/pmbr -SECTOR_SZ=512 - -# Rebuild ESP if stale -make all - -if [ ! -d "$ESP_DIR" ]; then - echo "ERROR: ESP directory '$ESP_DIR' not found. Run 'make all' first." - exit 1 -fi - -# Calculate required size: ESP contents + MBR gap + some slack -ESP_SIZE_MB=$(du -sm "$ESP_DIR" 2>/dev/null | cut -f1 || echo 1) -TOTAL_MB=$((ESP_SIZE_MB + MBR_SZ + 1)) # +1 MB slack - -echo "Creating ${TOTAL_MB} MB disk image: ${OUTPUT}" - -# Create empty image with MBR gap -dd if=/dev/zero of="$OUTPUT" bs=1M count="$TOTAL_MB" status=none 2>/dev/null - -# Partition table: single GPT partition, type EFI System (C12A7328-F81F-11D2-BA4B-00A0C93EC93B) -sgdisk --clear \ - --new=1:${MBR_SZ}M:0 \ - --typecode=1:C12A7328-F81F-11D2-BA4B-00A0C93EC93B \ - --change-name=1:"raisernics" \ - "$OUTPUT" >/dev/null - -# Find partition offset -PART_START=$(sgdisk --info=1 "$OUTPUT" 2>/dev/null | grep "Partition start sector" | awk '{print $NF}') -if [ -z "$PART_START" ]; then - PART_START=$((MBR_SZ * 1024 * 1024 / SECTOR_SZ)) -fi - -# Format as FAT32 -mformat -i "$OUTPUT"@$((PART_START * SECTOR_SZ)) -h 32 -s 32 -t "$((TOTAL_MB * 2))" >/dev/null 2>&1 || true - -# Copy the ESP contents onto the partition -mcopy -i "$OUTPUT"@$((PART_START * SECTOR_SZ)) -s "$ESP_DIR"/* ::/ 2>/dev/null - -echo " -> ${OUTPUT} ($(ls -lh "$OUTPUT" | awk '{print $5}'))" -echo "" -echo "To write to USB: sudo dd if=${OUTPUT} of=/dev/sdX bs=4M status=progress" -echo "To test with QEMU: qemu-system-x86_64 -bios -drive file=${OUTPUT},format=raw" diff --git a/tools/debug-kernel.py b/tools/debug-kernel.py deleted file mode 100755 index c794ad6..0000000 --- a/tools/debug-kernel.py +++ /dev/null @@ -1,64 +0,0 @@ -""" -GDB Python script for debugging raisernics under QEMU. - -Usage: - 1. Terminal 1: ./tools/qemu.sh --debug - 2. Terminal 2: gdb -x tools/debug-kernel.py target/x86_64-unknown-uefi/debug/raisernics.efi -""" - -import gdb -import os - -# Find the kernel binary -script_dir = os.path.dirname(os.path.abspath(__file__)) -project_root = os.path.dirname(script_dir) -binary = os.path.join( - project_root, - "target/x86_64-unknown-uefi/debug/raisernics.efi" -) - -# Connect to QEMU's GDB stub -gdb.execute("target remote :1234") - -# Load the binary (add symbol table) -if os.path.exists(binary): - gdb.execute(f"symbol-file {binary}") - print(f"Loaded symbols from {binary}") -else: - print(f"WARNING: {binary} not found. Build with debug symbols first.") - -gdb.execute("set breakpoint pending on") - - -# Helper commands -class DumpBootServices(gdb.Command): - """Dump EFI boot services signature and key pointers""" - - def __init__(self): - super().__init__("dump-bs", gdb.COMMAND_USER) - - def invoke(self, argument, from_tty): - del argument, from_tty - gdb.execute("printf \"SystemTable, BootServices, and key function pointers\\n\"") - gdb.execute("info functions efi_main") - - -class DumpGop(gdb.Command): - """Dump GOP framebuffer info""" - - def __init__(self): - super().__init__("dump-gop", gdb.COMMAND_USER) - - def invoke(self, argument, from_tty): - del argument, from_tty - gdb.execute("printf \"Check the gop::Framebuffer static\\n\"") - - -DumpBootServices() -DumpGop() - -print("") -print("raisernics GDB session ready.") -print(" target remote :1234 (connected)") -print(" Commands: continue, stepi, bt, info registers, etc.") -print(" Custom: dump-bs, dump-gop") diff --git a/tools/qemu.sh b/tools/qemu.sh deleted file mode 100755 index b75bed4..0000000 --- a/tools/qemu.sh +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env bash -# ============================================================================= -# tools/qemu.sh — Run raisernics in QEMU with various options -# -# Usage: -# ./tools/qemu.sh # serial console (no graphics) -# ./tools/qemu.sh --gui # graphical window -# ./tools/qemu.sh --debug # GDB stub on :1234 -# ./tools/qemu.sh --image foo.img # boot from raw disk image -# ./tools/qemu.sh --bios /path/to.fd # custom OVMF -# ./tools/qemu.sh --mem 512M # memory size -# ./tools/qemu.sh --smp 2 # SMP cores -# ============================================================================= -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)" -cd "$SCRIPT_DIR" - -# Defaults -GUI_FLAG="" -DEBUG_FLAG="" -DRIVE_ARGS=(-drive file=fat:rw:esp,format=raw) -OVMF="${OVMF:-/usr/share/edk2/x64/OVMF.4m.fd}" -MEM="${MEM:-256M}" -SMP="${SMP:-1}" - -# Pre-build -make all - -# Parse args -while [ $# -gt 0 ]; do - case "$1" in - --gui | -g) - GUI_FLAG="-vga std" - shift - ;; - --debug | -d) - DEBUG_FLAG="-s -S" - shift - ;; - --image | -i) - _img_file="$(printf -- '-drive file=%s,format=raw,if=none,id=hd' "$2")" - DRIVE_ARGS=("$_img_file" '-device' 'ide-hd,drive=hd') - shift 2 - ;; - --bios | -b) - OVMF="$2" - shift 2 - ;; - --mem) - MEM="$2" - shift 2 - ;; - --smp) - SMP="$2" - shift 2 - ;; - --help | -h) - head -20 "$0" | grep "^# " | sed 's/^# //' - exit 0 - ;; - *) - echo "Unknown option: $1" - exit 1 - ;; - esac -done - -QEMU_CMD=( - qemu-system-x86_64 - -bios "$OVMF" - "${DRIVE_ARGS[@]}" - -serial stdio - -m "$MEM" - -machine q35 - -cpu qemu64 - -no-reboot - -smp "$SMP" -) - -[ -n "$GUI_FLAG" ] && QEMU_CMD+=("$GUI_FLAG") -if [ -n "$DEBUG_FLAG" ]; then - # Split the flag string safely into words - read -ra dbg <<<"$DEBUG_FLAG" - QEMU_CMD+=("${dbg[@]}") -fi - -echo " OVMF : $OVMF" -echo " Drive : ${DRIVE_ARGS[*]}" -echo " Mem : $MEM" -echo " SMP : $SMP" -echo " GDB : $([ -n "$DEBUG_FLAG" ] && echo ':1234' || echo 'off')" -echo " GUI : $([ -n "$GUI_FLAG" ] && echo 'yes' || echo 'no')" -echo "" - -exec "${QEMU_CMD[@]}" -- cgit v1.2.3