summaryrefslogtreecommitdiffstats
path: root/scripts/mksystem.sh
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xscripts/mksystem.sh184
1 files changed, 184 insertions, 0 deletions
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 @@
1#!/usr/bin/env bash
2#
3# scripts/mksystem.sh — assemble the single dd-able rs-dos system image
4#
5# Replaces the old two-source setup (vvfat `esp/` directory for boot +
6# separate /tmp/disk.img for data). One FAT32 image holds EVERYTHING:
7#
8# \bzImage kernel (rsbl requires this exact path)
9# \initramfs.cpio.gz empty initramfs (rsbl requires it)
10# \EFI\BOOT\BOOTX64.EFI boot entry: the kernel (default) or rsboot
11# \etc\motd.txt seed config
12# \bin\cli\ \bin\gui\ binary tree (empty until Phase 2/4 migrate tools)
13# \*.txt seed files (seed/)
14#
15# The firmware boots from this image and the kernel mounts the same
16# volume at /disk/<UID>/ — boot medium and data medium are one disk.
17#
18# Usage:
19# ./scripts/mksystem.sh [options] [output.img] # default /tmp/system.img
20#
21# Options:
22# --force rebuild even if the image exists (Makefile stamps handle
23# normal freshness; without --force an existing image is kept,
24# so user files survive across reboots)
25# --size NM image size in MB (default 64)
26# --chain \EFI\BOOT\BOOTX64.EFI = rsboot bootloader (full chain:
27# firmware → rsboot → rsnix). Default is the kernel itself
28# (direct: firmware → rsnix), matching the old dev loop.
29# --gpt wrap the FAT volume in a GPT partition table (for dd-ing
30# to real USB sticks whose firmware refuses superfloppies)
31# --label NAME FAT volume label (default RSDOS)
32#
33set -euo pipefail
34
35SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
36PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
37cd "$PROJECT_DIR"
38
39IMG="/tmp/system.img"
40SIZE_MB=64
41FORCE=0
42CHAIN=0
43GPT=0
44LABEL="RSDOS"
45
46while [ $# -gt 0 ]; do
47 case "$1" in
48 --force | --fresh)
49 FORCE=1
50 ;;
51 --size)
52 shift
53 SIZE_MB="$1"
54 ;;
55 --chain)
56 CHAIN=1
57 ;;
58 --gpt)
59 GPT=1
60 ;;
61 --label)
62 shift
63 LABEL="$1"
64 ;;
65 --help | -h)
66 head -30 "$0" | grep "^#" | sed 's/^# \?//'
67 exit 0
68 ;;
69 -*)
70 echo "mksystem: unknown option: $1" >&2
71 exit 1
72 ;;
73 *)
74 IMG="$1"
75 ;;
76 esac
77 shift
78done
79
80TARGET=x86_64-unknown-uefi
81PROFILE=debug
82OUT_DIR="target/$TARGET/$PROFILE"
83KERNEL="$OUT_DIR/rsdos.efi"
84BZIMAGE="esp/bzImage"
85INITRD="esp/initramfs.cpio.gz"
86BOOTLOADER="build/bootloader/BOOTX64.EFI"
87
88# ---- checks ----
89for cmd in mkfs.fat mcopy mmd; do
90 if ! command -v "$cmd" >/dev/null 2>&1; then
91 echo "mksystem: $cmd not found (install dosfstools + mtools)" >&2
92 exit 1
93 fi
94done
95if [ "$GPT" -eq 1 ]; then
96 for cmd in sfdisk truncate dd; do
97 if ! command -v "$cmd" >/dev/null 2>&1; then
98 echo "mksystem: --gpt needs $cmd" >&2
99 exit 1
100 fi
101 done
102fi
103
104if [ -f "$IMG" ] && [ "$FORCE" -eq 0 ]; then
105 echo "mksystem: $IMG already exists (use --force to re-create)"
106 exit 0
107fi
108
109# ---- build kernel ----
110if [ ! -f "$KERNEL" ]; then
111 echo "mksystem: building kernel..."
112 cargo build --package rsdos --target "$TARGET"
113fi
114
115# ---- build bootloader (chain mode only) ----
116if [ "$CHAIN" -eq 1 ] && [ ! -f "$BOOTLOADER" ]; then
117 echo "mksystem: building bootloader..."
118 "$SCRIPT_DIR/build-bootloader.sh"
119fi
120
121# ---- deploy kernel artifacts to esp/ (shared with the old layout) ----
122mkdir -p esp/EFI/BOOT
123cp "$KERNEL" "$BZIMAGE"
124[ -f "$INITRD" ] || printf '' | gzip >"$INITRD"
125
126# ---- create the FAT volume ----
127rm -f "$IMG"
128SIZE_BLOCKS=$((SIZE_MB * 1024)) # mkfs.fat counts 1024-byte blocks
129echo "mksystem: creating $IMG (${SIZE_MB}M FAT32, label $LABEL)"
130mkfs.fat -C -F 32 -n "$LABEL" "$IMG" "$SIZE_BLOCKS" >/dev/null
131
132echo "mksystem: staging system tree"
133mmd -i "$IMG" ::/EFI ::/EFI/BOOT ::/etc ::/bin ::/bin/cli ::/bin/gui
134mcopy -i "$IMG" "$BZIMAGE" ::/bzImage
135mcopy -i "$IMG" "$INITRD" ::/initramfs.cpio.gz
136if [ "$CHAIN" -eq 1 ]; then
137 mcopy -i "$IMG" "$BOOTLOADER" ::/EFI/BOOT/BOOTX64.EFI
138 echo " \\EFI\\BOOT\\BOOTX64.EFI <- rsboot (full chain)"
139else
140 mcopy -i "$IMG" "$KERNEL" ::/EFI/BOOT/BOOTX64.EFI
141 echo " \\EFI\\BOOT\\BOOTX64.EFI <- kernel (direct)"
142fi
143echo " \\bzImage \\initramfs.cpio.gz \\bin{\\cli,\\gui} \\etc"
144
145# Seed files: motd lives in \etc, everything else at the volume root.
146SEED_DIR="$PROJECT_DIR/seed"
147if [ -d "$SEED_DIR" ]; then
148 for f in "$SEED_DIR"/*; do
149 [ -f "$f" ] || continue
150 name="$(basename "$f")"
151 if [ "$name" = "motd.txt" ]; then
152 mcopy -i "$IMG" "$f" ::/etc/"$name"
153 echo " \\etc\\$name"
154 else
155 mcopy -i "$IMG" "$f" ::/"$name"
156 echo " \\$name"
157 fi
158 done
159fi
160
161# ---- optional GPT wrapper (real-hardware dd target) ----
162if [ "$GPT" -eq 1 ]; then
163 GPT_START=2048 # 1 MiB offset (standard alignment)
164 GPT_IMG="$(mktemp)"
165 truncate -s "${SIZE_MB}M" "$GPT_IMG"
166 dd if="$IMG" of="$GPT_IMG" bs=512 seek="$GPT_START" conv=notrunc 2>/dev/null
167 FINAL="$(mktemp)"
168 truncate -s "$((SIZE_MB + 2))M" "$FINAL"
169 sfdisk --quiet "$FINAL" <<EOF
170label: gpt
171type=U, start=$GPT_START, size=
172EOF
173 dd if="$GPT_IMG" of="$FINAL" bs=512 seek="$GPT_START" conv=notrunc 2>/dev/null
174 rm -f "$GPT_IMG"
175 mv "$FINAL" "$IMG"
176 echo "mksystem: wrapped in GPT (partition at LBA $GPT_START)"
177fi
178
179echo ""
180echo "=== Done: $IMG ==="
181ls -lh "$IMG"
182echo "Boot with: make run (or: make boot-image)"
183[ "$GPT" -eq 0 ] && echo "USB dd tip: add --gpt for firmwares that refuse superfloppies"
184exit 0