summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/boot-image.sh87
-rwxr-xr-xscripts/boot.sh100
-rwxr-xr-xscripts/build-bootloader.sh32
-rwxr-xr-xscripts/build-image.sh99
-rwxr-xr-xscripts/debug-kernel.py64
-rwxr-xr-xscripts/qemu.sh96
6 files changed, 478 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#
20set -euo pipefail
21
22SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
23PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
24
25cd "$PROJECT_DIR"
26
27IMAGE="rs-dos.img"
28
29# ---- config ----
30OVMF="${OVMF:-/usr/share/edk2/x64/OVMF.4m.fd}"
31MEM="${MEM:-256M}"
32SMP="${SMP:-1}"
33GUI=""
34DEBUG=""
35
36# ---- args ----
37while [ $# -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
59done
60
61# ---- build image if missing ----
62if [ ! -f "$IMAGE" ]; then
63 echo "Image not found, building..."
64 "$SCRIPT_DIR/build-image.sh"
65fi
66
67# ---- boot ----
68echo ""
69echo "=== Booting (full chain: firmware → rsboot → rsnix) ==="
70echo " image: $IMAGE"
71echo " ovmf: $OVMF"
72echo " mem: $MEM smp: $SMP"
73echo " gui: $([ -n "$GUI" ] && echo yes || echo no)"
74echo " gdb: $([ -n "$DEBUG" ] && echo ':1234' || echo off)"
75echo ""
76
77exec 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#
23set -euo pipefail
24
25SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
26PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
27
28cd "$PROJECT_DIR"
29
30ESP_DIR="$PROJECT_DIR/esp"
31
32# ---- config ----
33OVMF="${OVMF:-/usr/share/edk2/x64/OVMF.4m.fd}"
34MEM="${MEM:-256M}"
35SMP="${SMP:-1}"
36PROFILE="debug"
37CARGO_FLAGS=""
38GUI=""
39DEBUG=""
40
41# ---- args ----
42while [ $# -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
68done
69
70OUT_DIR="target/x86_64-unknown-uefi/$PROFILE"
71KERNEL="$OUT_DIR/rsdos.efi"
72
73# ---- build ----
74echo "=== Building kernel ($PROFILE) ==="
75cargo build --package rsdos --target x86_64-unknown-uefi $CARGO_FLAGS
76
77# ---- deploy ----
78mkdir -p "$ESP_DIR/EFI/BOOT"
79cp "$KERNEL" "$ESP_DIR/EFI/BOOT/BOOTX64.EFI"
80echo " kernel: $(ls -lh "$KERNEL" | awk '{print $5}')"
81
82# ---- boot ----
83echo ""
84echo "=== Booting (direct: firmware → rsnix) ==="
85echo " ovmf: $OVMF"
86echo " mem: $MEM smp: $SMP"
87echo " gui: $([ -n "$GUI" ] && echo yes || echo no)"
88echo " gdb: $([ -n "$DEBUG" ] && echo ':1234' || echo off)"
89echo ""
90
91exec 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#
14set -euo pipefail
15
16SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
17PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
18BUILD_DIR="$PROJECT_DIR/build"
19BOOTLOADER_DIR="$BUILD_DIR/bootloader"
20
21echo "=== Building rsboot (UEFI bootloader) ==="
22
23# Ensure submodule is checked out
24git submodule update --init "$PROJECT_DIR/rsboot"
25
26cd "$PROJECT_DIR/rsboot"
27make clean 2>/dev/null || true
28make -j"$(nproc)" 2>&1 | sed 's/^/ /'
29
30echo ""
31echo "=== rsboot build complete ==="
32ls -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#
14set -euo pipefail
15
16SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
17PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
18
19cd "$PROJECT_DIR"
20
21BUILD_DIR="$PROJECT_DIR/build"
22ESP_DIR="$PROJECT_DIR/esp"
23
24IMAGE="${1:-$PROJECT_DIR/rs-dos.img}"
25TARGET=x86_64-unknown-uefi
26PROFILE=debug
27OUT_DIR="target/${TARGET}/${PROFILE}"
28
29BOOTLOADER="$BUILD_DIR/bootloader/BOOTX64.EFI"
30KERNEL="$OUT_DIR/rsdos.efi"
31BZIMAGE="$ESP_DIR/bzImage"
32INITRD="$ESP_DIR/initramfs.cpio.gz"
33BOOT_EFI="$ESP_DIR/EFI/BOOT/BOOTX64.EFI"
34
35ESP_START=2048 # 1 MiB offset (standard alignment)
36ESP_SIZE_MB=64
37
38IMAGE_SIZE_MB=$((ESP_SIZE_MB + 2)) # ESP + GPT gap + backup
39
40# ---- checks ----
41for 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
46done
47
48# ---- build kernel ----
49echo "[1/4] Building kernel..."
50cargo build --package rsdos --target x86_64-unknown-uefi ${CARGO_FLAGS:-}
51
52# ---- build bootloader ----
53echo "[2/4] Building bootloader..."
54if [ ! -f "$BOOTLOADER" ]; then
55 "$SCRIPT_DIR/build-bootloader.sh"
56fi
57
58# ---- assemble ESP ----
59echo "[3/4] Assembling ESP..."
60mkdir -p "$ESP_DIR/EFI/BOOT"
61cp "$KERNEL" "$BZIMAGE"
62cp "$BOOTLOADER" "$BOOT_EFI"
63if [ ! -f "$INITRD" ]; then
64 printf '' | gzip >"$INITRD"
65fi
66
67# ---- create disk image ----
68echo "[4/4] Writing disk image..."
69rm -f "$IMAGE"
70truncate -s "${IMAGE_SIZE_MB}M" "$IMAGE"
71
72# GPT partition table: single EFI System partition
73sfdisk --quiet "$IMAGE" <<EOF
74label: gpt
75type=U, start=$ESP_START, size=+
76EOF
77
78# Build FAT32 image with ESP contents
79ESP_IMG=$(mktemp)
80truncate -s "${ESP_SIZE_MB}M" "$ESP_IMG"
81mkfs.vfat -F 32 -n "RS-DOS" "$ESP_IMG" >/dev/null 2>&1
82
83# Copy files into FAT
84mmd -i "$ESP_IMG" ::/EFI 2>/dev/null || true
85mmd -i "$ESP_IMG" ::/EFI/BOOT 2>/dev/null || true
86mcopy -i "$ESP_IMG" "$BOOT_EFI" ::/EFI/BOOT/BOOTX64.EFI
87mcopy -i "$ESP_IMG" "$BZIMAGE" ::/bzImage 2>/dev/null || true
88mcopy -i "$ESP_IMG" "$INITRD" ::/initramfs.cpio.gz 2>/dev/null || true
89
90# Inject FAT into image at partition offset
91dd if="$ESP_IMG" of="$IMAGE" bs=512 seek="$ESP_START" conv=notrunc 2>/dev/null
92rm -f "$ESP_IMG"
93
94echo ""
95echo "=== Done: $IMAGE ==="
96ls -lh "$IMAGE"
97echo ""
98echo "Boot with: ./scripts/boot-image.sh"
99echo "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 @@
1"""
2GDB Python script for debugging raisernics under QEMU.
3
4Usage:
5 1. Terminal 1: ./tools/qemu.sh --debug
6 2. Terminal 2: gdb -x tools/debug-kernel.py target/x86_64-unknown-uefi/debug/raisernics.efi
7"""
8
9import gdb
10import os
11
12# Find the kernel binary
13script_dir = os.path.dirname(os.path.abspath(__file__))
14project_root = os.path.dirname(script_dir)
15binary = os.path.join(
16 project_root,
17 "target/x86_64-unknown-uefi/debug/raisernics.efi"
18)
19
20# Connect to QEMU's GDB stub
21gdb.execute("target remote :1234")
22
23# Load the binary (add symbol table)
24if os.path.exists(binary):
25 gdb.execute(f"symbol-file {binary}")
26 print(f"Loaded symbols from {binary}")
27else:
28 print(f"WARNING: {binary} not found. Build with debug symbols first.")
29
30gdb.execute("set breakpoint pending on")
31
32
33# Helper commands
34class DumpBootServices(gdb.Command):
35 """Dump EFI boot services signature and key pointers"""
36
37 def __init__(self):
38 super().__init__("dump-bs", gdb.COMMAND_USER)
39
40 def invoke(self, argument, from_tty):
41 del argument, from_tty
42 gdb.execute("printf \"SystemTable, BootServices, and key function pointers\\n\"")
43 gdb.execute("info functions efi_main")
44
45
46class DumpGop(gdb.Command):
47 """Dump GOP framebuffer info"""
48
49 def __init__(self):
50 super().__init__("dump-gop", gdb.COMMAND_USER)
51
52 def invoke(self, argument, from_tty):
53 del argument, from_tty
54 gdb.execute("printf \"Check the gop::Framebuffer static\\n\"")
55
56
57DumpBootServices()
58DumpGop()
59
60print("")
61print("raisernics GDB session ready.")
62print(" target remote :1234 (connected)")
63print(" Commands: continue, stepi, bt, info registers, etc.")
64print(" 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 @@
1#!/usr/bin/env bash
2# =============================================================================
3# tools/qemu.sh — Run raisernics in QEMU with various options
4#
5# Usage:
6# ./tools/qemu.sh # serial console (no graphics)
7# ./tools/qemu.sh --gui # graphical window
8# ./tools/qemu.sh --debug # GDB stub on :1234
9# ./tools/qemu.sh --image foo.img # boot from raw disk image
10# ./tools/qemu.sh --bios /path/to.fd # custom OVMF
11# ./tools/qemu.sh --mem 512M # memory size
12# ./tools/qemu.sh --smp 2 # SMP cores
13# =============================================================================
14set -euo pipefail
15
16SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
17cd "$SCRIPT_DIR"
18
19# Defaults
20GUI_FLAG=""
21DEBUG_FLAG=""
22DRIVE_ARGS=(-drive file=fat:rw:esp,format=raw)
23OVMF="${OVMF:-/usr/share/edk2/x64/OVMF.4m.fd}"
24MEM="${MEM:-256M}"
25SMP="${SMP:-1}"
26
27# Pre-build
28make all
29
30# Parse args
31while [ $# -gt 0 ]; do
32 case "$1" in
33 --gui | -g)
34 GUI_FLAG="-vga std"
35 shift
36 ;;
37 --debug | -d)
38 DEBUG_FLAG="-s -S"
39 shift
40 ;;
41 --image | -i)
42 _img_file="$(printf -- '-drive file=%s,format=raw,if=none,id=hd' "$2")"
43 DRIVE_ARGS=("$_img_file" '-device' 'ide-hd,drive=hd')
44 shift 2
45 ;;
46 --bios | -b)
47 OVMF="$2"
48 shift 2
49 ;;
50 --mem)
51 MEM="$2"
52 shift 2
53 ;;
54 --smp)
55 SMP="$2"
56 shift 2
57 ;;
58 --help | -h)
59 head -20 "$0" | grep "^# " | sed 's/^# //'
60 exit 0
61 ;;
62 *)
63 echo "Unknown option: $1"
64 exit 1
65 ;;
66 esac
67done
68
69QEMU_CMD=(
70 qemu-system-x86_64
71 -bios "$OVMF"
72 "${DRIVE_ARGS[@]}"
73 -serial stdio
74 -m "$MEM"
75 -machine q35
76 -cpu qemu64
77 -no-reboot
78 -smp "$SMP"
79)
80
81[ -n "$GUI_FLAG" ] && QEMU_CMD+=("$GUI_FLAG")
82if [ -n "$DEBUG_FLAG" ]; then
83 # Split the flag string safely into words
84 read -ra dbg <<<"$DEBUG_FLAG"
85 QEMU_CMD+=("${dbg[@]}")
86fi
87
88echo " OVMF : $OVMF"
89echo " Drive : ${DRIVE_ARGS[*]}"
90echo " Mem : $MEM"
91echo " SMP : $SMP"
92echo " GDB : $([ -n "$DEBUG_FLAG" ] && echo ':1234' || echo 'off')"
93echo " GUI : $([ -n "$GUI_FLAG" ] && echo 'yes' || echo 'no')"
94echo ""
95
96exec "${QEMU_CMD[@]}"