diff options
Diffstat (limited to '')
| -rwxr-xr-x | scripts/boot-image.sh | 87 | ||||
| -rwxr-xr-x | scripts/boot.sh | 100 | ||||
| -rwxr-xr-x | scripts/build-bootloader.sh | 32 | ||||
| -rwxr-xr-x | scripts/build-image.sh | 99 | ||||
| -rwxr-xr-x | scripts/debug-kernel.py (renamed from tools/debug-kernel.py) | 0 | ||||
| -rwxr-xr-x | scripts/qemu.sh (renamed from tools/qemu.sh) | 0 |
6 files changed, 318 insertions, 0 deletions
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 @@ | |||
| 1 | #!/usr/bin/env bash | ||
| 2 | # | ||
| 3 | # scripts/boot-image.sh — boot rs-dos full chain disk image in QEMU | ||
| 4 | # | ||
| 5 | # Builds the image first if needed, then boots with UEFI firmware through | ||
| 6 | # the real boot chain: firmware → rsboot → rsnix kernel. | ||
| 7 | # | ||
| 8 | # Usage: | ||
| 9 | # ./scripts/boot-image.sh [--gui] [--debug] [--mem 512M] [--smp 2] | ||
| 10 | # | ||
| 11 | # Keybindings: | ||
| 12 | # Ctrl-A X — quit | ||
| 13 | # Ctrl-A C — QEMU monitor | ||
| 14 | # | ||
| 15 | # Environment: | ||
| 16 | # OVMF path to OVMF firmware (default: /usr/share/edk2/x64/OVMF.4m.fd) | ||
| 17 | # MEM memory size (default: 256M) | ||
| 18 | # SMP CPU count (default: 1) | ||
| 19 | # | ||
| 20 | set -euo pipefail | ||
| 21 | |||
| 22 | SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" | ||
| 23 | PROJECT_DIR="$(dirname "$SCRIPT_DIR")" | ||
| 24 | |||
| 25 | cd "$PROJECT_DIR" | ||
| 26 | |||
| 27 | IMAGE="rs-dos.img" | ||
| 28 | |||
| 29 | # ---- config ---- | ||
| 30 | OVMF="${OVMF:-/usr/share/edk2/x64/OVMF.4m.fd}" | ||
| 31 | MEM="${MEM:-256M}" | ||
| 32 | SMP="${SMP:-1}" | ||
| 33 | GUI="" | ||
| 34 | DEBUG="" | ||
| 35 | |||
| 36 | # ---- args ---- | ||
| 37 | while [ $# -gt 0 ]; do | ||
| 38 | case "$1" in | ||
| 39 | --gui | -g) GUI="-vga std" ;; | ||
| 40 | --debug | -d) DEBUG="-s -S" ;; | ||
| 41 | --mem) | ||
| 42 | shift | ||
| 43 | MEM="$1" | ||
| 44 | ;; | ||
| 45 | --smp) | ||
| 46 | shift | ||
| 47 | SMP="$1" | ||
| 48 | ;; | ||
| 49 | --help | -h) | ||
| 50 | head -20 "$0" | grep "^#" | sed 's/^# //' | ||
| 51 | exit 0 | ||
| 52 | ;; | ||
| 53 | *) | ||
| 54 | echo "unknown: $1" | ||
| 55 | exit 1 | ||
| 56 | ;; | ||
| 57 | esac | ||
| 58 | shift | ||
| 59 | done | ||
| 60 | |||
| 61 | # ---- build image if missing ---- | ||
| 62 | if [ ! -f "$IMAGE" ]; then | ||
| 63 | echo "Image not found, building..." | ||
| 64 | "$SCRIPT_DIR/build-image.sh" | ||
| 65 | fi | ||
| 66 | |||
| 67 | # ---- boot ---- | ||
| 68 | echo "" | ||
| 69 | echo "=== Booting (full chain: firmware → rsboot → rsnix) ===" | ||
| 70 | echo " image: $IMAGE" | ||
| 71 | echo " ovmf: $OVMF" | ||
| 72 | echo " mem: $MEM smp: $SMP" | ||
| 73 | echo " gui: $([ -n "$GUI" ] && echo yes || echo no)" | ||
| 74 | echo " gdb: $([ -n "$DEBUG" ] && echo ':1234' || echo off)" | ||
| 75 | echo "" | ||
| 76 | |||
| 77 | exec qemu-system-x86_64 \ | ||
| 78 | -bios "$OVMF" \ | ||
| 79 | -drive file="$IMAGE",format=raw,if=none,id=hd \ | ||
| 80 | -device ide-hd,drive=hd \ | ||
| 81 | -serial stdio \ | ||
| 82 | -m "$MEM" \ | ||
| 83 | -machine q35 \ | ||
| 84 | -cpu qemu64 \ | ||
| 85 | -no-reboot \ | ||
| 86 | -smp "$SMP" \ | ||
| 87 | $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 @@ | |||
| 1 | #!/usr/bin/env bash | ||
| 2 | # | ||
| 3 | # scripts/boot.sh — quick direct boot in QEMU (dev loop) | ||
| 4 | # | ||
| 5 | # Fastest iteration: boots the kernel directly as BOOTX64.EFI via QEMU's | ||
| 6 | # FAT driver, skipping the bootloader entirely. | ||
| 7 | # | ||
| 8 | # Usage: | ||
| 9 | # ./scripts/boot.sh [--gui] [--debug] [--release] [--mem 512M] [--smp 2] | ||
| 10 | # | ||
| 11 | # Boot chain: firmware → rsnix (direct) | ||
| 12 | # Full chain: use ./scripts/boot-image.sh (firmware → rsboot → rsnix) | ||
| 13 | # | ||
| 14 | # Keybindings: | ||
| 15 | # Ctrl-A X — quit | ||
| 16 | # Ctrl-A C — QEMU monitor | ||
| 17 | # | ||
| 18 | # Environment: | ||
| 19 | # OVMF path to OVMF firmware (default: /usr/share/edk2/x64/OVMF.4m.fd) | ||
| 20 | # MEM memory size (default: 256M) | ||
| 21 | # SMP CPU count (default: 1) | ||
| 22 | # | ||
| 23 | set -euo pipefail | ||
| 24 | |||
| 25 | SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" | ||
| 26 | PROJECT_DIR="$(dirname "$SCRIPT_DIR")" | ||
| 27 | |||
| 28 | cd "$PROJECT_DIR" | ||
| 29 | |||
| 30 | ESP_DIR="$PROJECT_DIR/esp" | ||
| 31 | |||
| 32 | # ---- config ---- | ||
| 33 | OVMF="${OVMF:-/usr/share/edk2/x64/OVMF.4m.fd}" | ||
| 34 | MEM="${MEM:-256M}" | ||
| 35 | SMP="${SMP:-1}" | ||
| 36 | PROFILE="debug" | ||
| 37 | CARGO_FLAGS="" | ||
| 38 | GUI="" | ||
| 39 | DEBUG="" | ||
| 40 | |||
| 41 | # ---- args ---- | ||
| 42 | while [ $# -gt 0 ]; do | ||
| 43 | case "$1" in | ||
| 44 | --gui | -g) GUI="-vga std" ;; | ||
| 45 | --debug | -d) DEBUG="-s -S" ;; | ||
| 46 | --release | -r) | ||
| 47 | PROFILE="release" | ||
| 48 | CARGO_FLAGS="--release" | ||
| 49 | ;; | ||
| 50 | --mem) | ||
| 51 | shift | ||
| 52 | MEM="$1" | ||
| 53 | ;; | ||
| 54 | --smp) | ||
| 55 | shift | ||
| 56 | SMP="$1" | ||
| 57 | ;; | ||
| 58 | --help | -h) | ||
| 59 | head -20 "$0" | grep "^#" | sed 's/^# //' | ||
| 60 | exit 0 | ||
| 61 | ;; | ||
| 62 | *) | ||
| 63 | echo "unknown: $1" | ||
| 64 | exit 1 | ||
| 65 | ;; | ||
| 66 | esac | ||
| 67 | shift | ||
| 68 | done | ||
| 69 | |||
| 70 | OUT_DIR="target/x86_64-unknown-uefi/$PROFILE" | ||
| 71 | KERNEL="$OUT_DIR/rsdos.efi" | ||
| 72 | |||
| 73 | # ---- build ---- | ||
| 74 | echo "=== Building kernel ($PROFILE) ===" | ||
| 75 | cargo build --package rsdos --target x86_64-unknown-uefi $CARGO_FLAGS | ||
| 76 | |||
| 77 | # ---- deploy ---- | ||
| 78 | mkdir -p "$ESP_DIR/EFI/BOOT" | ||
| 79 | cp "$KERNEL" "$ESP_DIR/EFI/BOOT/BOOTX64.EFI" | ||
| 80 | echo " kernel: $(ls -lh "$KERNEL" | awk '{print $5}')" | ||
| 81 | |||
| 82 | # ---- boot ---- | ||
| 83 | echo "" | ||
| 84 | echo "=== Booting (direct: firmware → rsnix) ===" | ||
| 85 | echo " ovmf: $OVMF" | ||
| 86 | echo " mem: $MEM smp: $SMP" | ||
| 87 | echo " gui: $([ -n "$GUI" ] && echo yes || echo no)" | ||
| 88 | echo " gdb: $([ -n "$DEBUG" ] && echo ':1234' || echo off)" | ||
| 89 | echo "" | ||
| 90 | |||
| 91 | exec qemu-system-x86_64 \ | ||
| 92 | -bios "$OVMF" \ | ||
| 93 | -drive file=fat:rw:"$ESP_DIR",format=raw \ | ||
| 94 | -serial stdio \ | ||
| 95 | -m "$MEM" \ | ||
| 96 | -machine q35 \ | ||
| 97 | -cpu qemu64 \ | ||
| 98 | -no-reboot \ | ||
| 99 | -smp "$SMP" \ | ||
| 100 | $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 @@ | |||
| 1 | #!/usr/bin/env bash | ||
| 2 | # | ||
| 3 | # scripts/build-bootloader.sh — build rsboot (UEFI bootloader) | ||
| 4 | # | ||
| 5 | # rsboot is a git submodule at rsboot/. This builds it and places | ||
| 6 | # BOOTX64.EFI into build/bootloader/. | ||
| 7 | # | ||
| 8 | # Usage: | ||
| 9 | # ./scripts/build-bootloader.sh | ||
| 10 | # | ||
| 11 | # Output: | ||
| 12 | # build/bootloader/BOOTX64.EFI | ||
| 13 | # | ||
| 14 | set -euo pipefail | ||
| 15 | |||
| 16 | SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" | ||
| 17 | PROJECT_DIR="$(dirname "$SCRIPT_DIR")" | ||
| 18 | BUILD_DIR="$PROJECT_DIR/build" | ||
| 19 | BOOTLOADER_DIR="$BUILD_DIR/bootloader" | ||
| 20 | |||
| 21 | echo "=== Building rsboot (UEFI bootloader) ===" | ||
| 22 | |||
| 23 | # Ensure submodule is checked out | ||
| 24 | git submodule update --init "$PROJECT_DIR/rsboot" | ||
| 25 | |||
| 26 | cd "$PROJECT_DIR/rsboot" | ||
| 27 | make clean 2>/dev/null || true | ||
| 28 | make -j"$(nproc)" 2>&1 | sed 's/^/ /' | ||
| 29 | |||
| 30 | echo "" | ||
| 31 | echo "=== rsboot build complete ===" | ||
| 32 | 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 @@ | |||
| 1 | #!/usr/bin/env bash | ||
| 2 | # | ||
| 3 | # scripts/build-image.sh — assemble a bootable rs-dos disk image (UEFI/GPT) | ||
| 4 | # | ||
| 5 | # Layout: | ||
| 6 | # Partition 1: ESP (FAT32) — rsboot bootloader + kernel | ||
| 7 | # | ||
| 8 | # Output: | ||
| 9 | # rs-dos.img (or custom path) — bootable raw disk image for UEFI | ||
| 10 | # | ||
| 11 | # Usage: | ||
| 12 | # ./scripts/build-image.sh [output.img] | ||
| 13 | # | ||
| 14 | set -euo pipefail | ||
| 15 | |||
| 16 | SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" | ||
| 17 | PROJECT_DIR="$(dirname "$SCRIPT_DIR")" | ||
| 18 | |||
| 19 | cd "$PROJECT_DIR" | ||
| 20 | |||
| 21 | BUILD_DIR="$PROJECT_DIR/build" | ||
| 22 | ESP_DIR="$PROJECT_DIR/esp" | ||
| 23 | |||
| 24 | IMAGE="${1:-$PROJECT_DIR/rs-dos.img}" | ||
| 25 | TARGET=x86_64-unknown-uefi | ||
| 26 | PROFILE=debug | ||
| 27 | OUT_DIR="target/${TARGET}/${PROFILE}" | ||
| 28 | |||
| 29 | BOOTLOADER="$BUILD_DIR/bootloader/BOOTX64.EFI" | ||
| 30 | KERNEL="$OUT_DIR/rsdos.efi" | ||
| 31 | BZIMAGE="$ESP_DIR/bzImage" | ||
| 32 | INITRD="$ESP_DIR/initramfs.cpio.gz" | ||
| 33 | BOOT_EFI="$ESP_DIR/EFI/BOOT/BOOTX64.EFI" | ||
| 34 | |||
| 35 | ESP_START=2048 # 1 MiB offset (standard alignment) | ||
| 36 | ESP_SIZE_MB=64 | ||
| 37 | |||
| 38 | IMAGE_SIZE_MB=$((ESP_SIZE_MB + 2)) # ESP + GPT gap + backup | ||
| 39 | |||
| 40 | # ---- checks ---- | ||
| 41 | for cmd in sfdisk mkfs.vfat mcopy truncate dd; do | ||
| 42 | if ! command -v "$cmd" &>/dev/null; then | ||
| 43 | echo "Error: $cmd not found" | ||
| 44 | exit 1 | ||
| 45 | fi | ||
| 46 | done | ||
| 47 | |||
| 48 | # ---- build kernel ---- | ||
| 49 | echo "[1/4] Building kernel..." | ||
| 50 | cargo build --package rsdos --target x86_64-unknown-uefi ${CARGO_FLAGS:-} | ||
| 51 | |||
| 52 | # ---- build bootloader ---- | ||
| 53 | echo "[2/4] Building bootloader..." | ||
| 54 | if [ ! -f "$BOOTLOADER" ]; then | ||
| 55 | "$SCRIPT_DIR/build-bootloader.sh" | ||
| 56 | fi | ||
| 57 | |||
| 58 | # ---- assemble ESP ---- | ||
| 59 | echo "[3/4] Assembling ESP..." | ||
| 60 | mkdir -p "$ESP_DIR/EFI/BOOT" | ||
| 61 | cp "$KERNEL" "$BZIMAGE" | ||
| 62 | cp "$BOOTLOADER" "$BOOT_EFI" | ||
| 63 | if [ ! -f "$INITRD" ]; then | ||
| 64 | printf '' | gzip >"$INITRD" | ||
| 65 | fi | ||
| 66 | |||
| 67 | # ---- create disk image ---- | ||
| 68 | echo "[4/4] Writing disk image..." | ||
| 69 | rm -f "$IMAGE" | ||
| 70 | truncate -s "${IMAGE_SIZE_MB}M" "$IMAGE" | ||
| 71 | |||
| 72 | # GPT partition table: single EFI System partition | ||
| 73 | sfdisk --quiet "$IMAGE" <<EOF | ||
| 74 | label: gpt | ||
| 75 | type=U, start=$ESP_START, size=+ | ||
| 76 | EOF | ||
| 77 | |||
| 78 | # Build FAT32 image with ESP contents | ||
| 79 | ESP_IMG=$(mktemp) | ||
| 80 | truncate -s "${ESP_SIZE_MB}M" "$ESP_IMG" | ||
| 81 | mkfs.vfat -F 32 -n "RS-DOS" "$ESP_IMG" >/dev/null 2>&1 | ||
| 82 | |||
| 83 | # Copy files into FAT | ||
| 84 | mmd -i "$ESP_IMG" ::/EFI 2>/dev/null || true | ||
| 85 | mmd -i "$ESP_IMG" ::/EFI/BOOT 2>/dev/null || true | ||
| 86 | mcopy -i "$ESP_IMG" "$BOOT_EFI" ::/EFI/BOOT/BOOTX64.EFI | ||
| 87 | mcopy -i "$ESP_IMG" "$BZIMAGE" ::/bzImage 2>/dev/null || true | ||
| 88 | mcopy -i "$ESP_IMG" "$INITRD" ::/initramfs.cpio.gz 2>/dev/null || true | ||
| 89 | |||
| 90 | # Inject FAT into image at partition offset | ||
| 91 | dd if="$ESP_IMG" of="$IMAGE" bs=512 seek="$ESP_START" conv=notrunc 2>/dev/null | ||
| 92 | rm -f "$ESP_IMG" | ||
| 93 | |||
| 94 | echo "" | ||
| 95 | echo "=== Done: $IMAGE ===" | ||
| 96 | ls -lh "$IMAGE" | ||
| 97 | echo "" | ||
| 98 | echo "Boot with: ./scripts/boot-image.sh" | ||
| 99 | echo "USB: sudo dd if=$IMAGE of=/dev/sdX bs=4M status=progress" | ||
diff --git a/tools/debug-kernel.py b/scripts/debug-kernel.py index c794ad6..c794ad6 100755 --- a/tools/debug-kernel.py +++ b/scripts/debug-kernel.py | |||
diff --git a/tools/qemu.sh b/scripts/qemu.sh index b75bed4..b75bed4 100755 --- a/tools/qemu.sh +++ b/scripts/qemu.sh | |||
