From 298528581d1a29032a1224600297316384d4e4f7 Mon Sep 17 00:00:00 2001 From: salmonik Date: Fri, 21 Aug 2026 19:13:52 +0200 Subject: image: single dd-able system.img replaces vvfat+data-disk pair MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mksystem.sh stages one FAT32 image: \bzImage + \initramfs.cpio.gz (rsbl paths), \EFI\BOOT\BOOTX64.EFI (kernel direct by default, --chain for rsboot), \etc\motd.txt, empty \bin\cli + \bin\gui, seed files at the root. --gpt wraps it in a partition table for real USB dd targets. Makefile: run/run-gui/debug attach only system.img on ide.0 (vvfat lines deleted); stamp-based 'system' target rebuilds only when the kernel is newer, so runtime writes survive reboots; system-fresh wipes; inspect lists via mtools. build-image.sh/mkdisk.sh removed. test-disk.sh boots system.img with a throwaway OVMF varstore — a stale NvVars makes the firmware skip the \EFI\BOOT fallback. sendkeys.py pacing 50ms->250ms/1.5s: keystroke loss under host load corrupted typed lines (guest-side PS/2 ring overflow). Gate: test-disk PASS (fsck clean, file survives poweroff). --- scripts/mksystem.sh | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100755 scripts/mksystem.sh (limited to 'scripts/mksystem.sh') diff --git a/scripts/mksystem.sh b/scripts/mksystem.sh new file mode 100755 index 0000000..dfa481c --- /dev/null +++ b/scripts/mksystem.sh @@ -0,0 +1,184 @@ +#!/usr/bin/env bash +# +# scripts/mksystem.sh — assemble the single dd-able rs-dos system image +# +# Replaces the old two-source setup (vvfat `esp/` directory for boot + +# separate /tmp/disk.img for data). One FAT32 image holds EVERYTHING: +# +# \bzImage kernel (rsbl requires this exact path) +# \initramfs.cpio.gz empty initramfs (rsbl requires it) +# \EFI\BOOT\BOOTX64.EFI boot entry: the kernel (default) or rsboot +# \etc\motd.txt seed config +# \bin\cli\ \bin\gui\ binary tree (empty until Phase 2/4 migrate tools) +# \*.txt seed files (seed/) +# +# The firmware boots from this image and the kernel mounts the same +# volume at /disk// — boot medium and data medium are one disk. +# +# Usage: +# ./scripts/mksystem.sh [options] [output.img] # default /tmp/system.img +# +# Options: +# --force rebuild even if the image exists (Makefile stamps handle +# normal freshness; without --force an existing image is kept, +# so user files survive across reboots) +# --size NM image size in MB (default 64) +# --chain \EFI\BOOT\BOOTX64.EFI = rsboot bootloader (full chain: +# firmware → rsboot → rsnix). Default is the kernel itself +# (direct: firmware → rsnix), matching the old dev loop. +# --gpt wrap the FAT volume in a GPT partition table (for dd-ing +# to real USB sticks whose firmware refuses superfloppies) +# --label NAME FAT volume label (default RSDOS) +# +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PROJECT_DIR="$(dirname "$SCRIPT_DIR")" +cd "$PROJECT_DIR" + +IMG="/tmp/system.img" +SIZE_MB=64 +FORCE=0 +CHAIN=0 +GPT=0 +LABEL="RSDOS" + +while [ $# -gt 0 ]; do + case "$1" in + --force | --fresh) + FORCE=1 + ;; + --size) + shift + SIZE_MB="$1" + ;; + --chain) + CHAIN=1 + ;; + --gpt) + GPT=1 + ;; + --label) + shift + LABEL="$1" + ;; + --help | -h) + head -30 "$0" | grep "^#" | sed 's/^# \?//' + exit 0 + ;; + -*) + echo "mksystem: unknown option: $1" >&2 + exit 1 + ;; + *) + IMG="$1" + ;; + esac + shift +done + +TARGET=x86_64-unknown-uefi +PROFILE=debug +OUT_DIR="target/$TARGET/$PROFILE" +KERNEL="$OUT_DIR/rsdos.efi" +BZIMAGE="esp/bzImage" +INITRD="esp/initramfs.cpio.gz" +BOOTLOADER="build/bootloader/BOOTX64.EFI" + +# ---- checks ---- +for cmd in mkfs.fat mcopy mmd; do + if ! command -v "$cmd" >/dev/null 2>&1; then + echo "mksystem: $cmd not found (install dosfstools + mtools)" >&2 + exit 1 + fi +done +if [ "$GPT" -eq 1 ]; then + for cmd in sfdisk truncate dd; do + if ! command -v "$cmd" >/dev/null 2>&1; then + echo "mksystem: --gpt needs $cmd" >&2 + exit 1 + fi + done +fi + +if [ -f "$IMG" ] && [ "$FORCE" -eq 0 ]; then + echo "mksystem: $IMG already exists (use --force to re-create)" + exit 0 +fi + +# ---- build kernel ---- +if [ ! -f "$KERNEL" ]; then + echo "mksystem: building kernel..." + cargo build --package rsdos --target "$TARGET" +fi + +# ---- build bootloader (chain mode only) ---- +if [ "$CHAIN" -eq 1 ] && [ ! -f "$BOOTLOADER" ]; then + echo "mksystem: building bootloader..." + "$SCRIPT_DIR/build-bootloader.sh" +fi + +# ---- deploy kernel artifacts to esp/ (shared with the old layout) ---- +mkdir -p esp/EFI/BOOT +cp "$KERNEL" "$BZIMAGE" +[ -f "$INITRD" ] || printf '' | gzip >"$INITRD" + +# ---- create the FAT volume ---- +rm -f "$IMG" +SIZE_BLOCKS=$((SIZE_MB * 1024)) # mkfs.fat counts 1024-byte blocks +echo "mksystem: creating $IMG (${SIZE_MB}M FAT32, label $LABEL)" +mkfs.fat -C -F 32 -n "$LABEL" "$IMG" "$SIZE_BLOCKS" >/dev/null + +echo "mksystem: staging system tree" +mmd -i "$IMG" ::/EFI ::/EFI/BOOT ::/etc ::/bin ::/bin/cli ::/bin/gui +mcopy -i "$IMG" "$BZIMAGE" ::/bzImage +mcopy -i "$IMG" "$INITRD" ::/initramfs.cpio.gz +if [ "$CHAIN" -eq 1 ]; then + mcopy -i "$IMG" "$BOOTLOADER" ::/EFI/BOOT/BOOTX64.EFI + echo " \\EFI\\BOOT\\BOOTX64.EFI <- rsboot (full chain)" +else + mcopy -i "$IMG" "$KERNEL" ::/EFI/BOOT/BOOTX64.EFI + echo " \\EFI\\BOOT\\BOOTX64.EFI <- kernel (direct)" +fi +echo " \\bzImage \\initramfs.cpio.gz \\bin{\\cli,\\gui} \\etc" + +# Seed files: motd lives in \etc, everything else at the volume root. +SEED_DIR="$PROJECT_DIR/seed" +if [ -d "$SEED_DIR" ]; then + for f in "$SEED_DIR"/*; do + [ -f "$f" ] || continue + name="$(basename "$f")" + if [ "$name" = "motd.txt" ]; then + mcopy -i "$IMG" "$f" ::/etc/"$name" + echo " \\etc\\$name" + else + mcopy -i "$IMG" "$f" ::/"$name" + echo " \\$name" + fi + done +fi + +# ---- optional GPT wrapper (real-hardware dd target) ---- +if [ "$GPT" -eq 1 ]; then + GPT_START=2048 # 1 MiB offset (standard alignment) + GPT_IMG="$(mktemp)" + truncate -s "${SIZE_MB}M" "$GPT_IMG" + dd if="$IMG" of="$GPT_IMG" bs=512 seek="$GPT_START" conv=notrunc 2>/dev/null + FINAL="$(mktemp)" + truncate -s "$((SIZE_MB + 2))M" "$FINAL" + sfdisk --quiet "$FINAL" </dev/null + rm -f "$GPT_IMG" + mv "$FINAL" "$IMG" + echo "mksystem: wrapped in GPT (partition at LBA $GPT_START)" +fi + +echo "" +echo "=== Done: $IMG ===" +ls -lh "$IMG" +echo "Boot with: make run (or: make boot-image)" +[ "$GPT" -eq 0 ] && echo "USB dd tip: add --gpt for firmwares that refuse superfloppies" +exit 0 -- cgit v1.2.3