summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-07-31 03:22:20 +0200
committersalmonik <salmonik@tuta.io>2026-07-31 03:22:20 +0200
commit0ace22d6f88692883584119c64ff010f4cee6738 (patch)
tree6f575f9088dec8bab90943d6c23e174bca183f0a
parentrestructure: rsnix kernel + shell crate + rsdos entry point (diff)
downloadrs-dos-0ace22d6f88692883584119c64ff010f4cee6738.tar.gz
rs-dos-0ace22d6f88692883584119c64ff010f4cee6738.zip
fix(rsdos): organizational changes
Diffstat (limited to '')
-rw-r--r--.gitignore1
-rw-r--r--.gitmodules3
-rw-r--r--CONTEXT.md2
-rw-r--r--Makefile56
m---------rsboot0
-rw-r--r--rsnix/src/interrupts.rs2
-rw-r--r--rsnix/src/lib.rs8
-rw-r--r--rsnix/src/ps2.rs7
-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.py (renamed from tools/debug-kernel.py)0
-rwxr-xr-xscripts/qemu.sh (renamed from tools/qemu.sh)0
-rwxr-xr-xtools/boot-image.sh62
15 files changed, 362 insertions, 97 deletions
diff --git a/.gitignore b/.gitignore
index 2353fdc..42b56cf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
1/target 1/target
2/build
2/esp/ 3/esp/
3*.img 4*.img
4NvVars 5NvVars
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..423167d
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
1[submodule "rsboot"]
2 path = rsboot
3 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:
87 87
88## Milestone status (v0.1) 88## Milestone status (v0.1)
89 89
90✅ **Booting** — kernel loads via rsbl, prints banner via UEFI console 90✅ **Booting** — kernel loads via rsbl, prints banner via UEFI console (verified on real hardware)
91✅ **ExitBootServices** — memory map captured via static `.bss` buffer 91✅ **ExitBootServices** — memory map captured via static `.bss` buffer
92 (see `docs/adr/0001-static-buffer-for-memory-map.md`) 92 (see `docs/adr/0001-static-buffer-for-memory-map.md`)
93✅ **Serial** — UART 16550 at COM1, 115200 8N1 93✅ **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
11export OVMF=/usr/share/edk2/x64/OVMF.4m.fd 11export OVMF=/usr/share/edk2/x64/OVMF.4m.fd
12export BOOT_EFI=$(ESP_DIR)/EFI/BOOT/BOOTX64.EFI 12export BOOT_EFI=$(ESP_DIR)/EFI/BOOT/BOOTX64.EFI
13 13
14.PHONY: all run run-gui clean image debug release fmt 14.PHONY: all run run-gui clean image debug release fmt bootloader boot-image
15 15
16# ---- Build --------------------------------------------------------------- 16# ---- Build ---------------------------------------------------------------
17 17
@@ -75,23 +75,24 @@ debug: all
75 -display none \ 75 -display none \
76 -s -S 76 -s -S
77 77
78# Boot from a raw disk image (created by tools/boot-image.sh) 78# Boot from a raw disk image (delegates to boot-image.sh which builds the
79# full chain if the image doesn't exist yet)
79run-image: all 80run-image: all
80 qemu-system-x86_64 \ 81 ./scripts/boot-image.sh rs-dos.img
81 -bios $(OVMF) \
82 -drive file=$(IMG),format=raw,if=none,id=hd \
83 -device ide-hd,drive=hd \
84 -serial stdio \
85 -m 256M \
86 -machine q35 \
87 -cpu qemu64 \
88 -no-reboot \
89 -display none
90 82
91# ---- Disk image ---------------------------------------------------------- 83# ---- Full boot chain -----------------------------------------------------
92 84
85# Build bootloader only (rsboot submodule)
86bootloader:
87 ./scripts/build-bootloader.sh
88
89# Build the full boot chain disk image (kernel + bootloader)
93image: all 90image: all
94 ./tools/boot-image.sh rs-dos.img 91 ./scripts/build-image.sh rs-dos.img
92
93# Boot the full chain disk image (builds it first if needed)
94boot-image: all
95 ./scripts/boot-image.sh rs-dos.img
95 96
96# ---- Utilities ----------------------------------------------------------- 97# ---- Utilities -----------------------------------------------------------
97 98
@@ -105,16 +106,21 @@ clean:
105help: 106help:
106 @echo "rs-dos — Make targets" 107 @echo "rs-dos — Make targets"
107 @echo "" 108 @echo ""
108 @echo " make build kernel + ESP (default)" 109 @echo " make build kernel + ESP (default)"
109 @echo " make release build with --release (smaller binary)" 110 @echo " make release build with --release (smaller binary)"
110 @echo " make image create bootable USB image (rs-dos.img)" 111 @echo " make bootloader build rsboot from source"
111 @echo " make run QEMU serial console (no graphics)" 112 @echo " make image build full chain disk image (bootloader + kernel)"
112 @echo " make run-gui QEMU with graphical window (GOP/PS2)" 113 @echo " make boot-image build + boot full chain via QEMU"
113 @echo " make debug QEMU + GDB stub on :1234" 114 @echo " make run QEMU serial console (direct boot, no bootloader)"
114 @echo " make clean remove build artifacts" 115 @echo " make run-gui QEMU with graphical window (GOP/PS2)"
115 @echo " make fmt format Rust source" 116 @echo " make debug QEMU + GDB stub on :1234"
117 @echo " make clean remove build artifacts"
118 @echo " make fmt format Rust source"
116 @echo "" 119 @echo ""
117 @echo "Scripts:" 120 @echo "Scripts:"
118 @echo " ./tools/qemu.sh flexible QEMU launcher" 121 @echo " ./scripts/boot.sh quick direct boot (dev loop)"
119 @echo " ./tools/boot-image.sh create bootable disk image" 122 @echo " ./scripts/boot-image.sh boot full chain (builds if needed)"
120 @echo " ./tools/debug-kernel.py GDB plugin (attach after 'make debug')" 123 @echo " ./scripts/build-image.sh build full chain disk image"
124 @echo " ./scripts/build-bootloader.sh build rsboot from source"
125 @echo " ./scripts/qemu.sh flexible QEMU launcher"
126 @echo " ./scripts/debug-kernel.py GDB plugin (attach after 'make debug')"
diff --git a/rsboot b/rsboot
new file mode 160000
Subproject 1963a0a6d7398a426d0701f90a5bc796e32899a
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() {
362 362
363 // Build the IDTR pseudo-descriptor. 363 // Build the IDTR pseudo-descriptor.
364 IDTR = [ 364 IDTR = [
365 ((256u16 * 16 - 1)), // limit = 256*16 - 1 365 (256u16 * 16 - 1), // limit = 256*16 - 1
366 idt_ptr as u16, // base lo 366 idt_ptr as u16, // base lo
367 (idt_ptr as u64 >> 16) as u16, // base mid 367 (idt_ptr as u64 >> 16) as u16, // base mid
368 (idt_ptr as u64 >> 32) as u16, // base hi 368 (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 @@
2 2
3extern crate alloc; 3extern crate alloc;
4 4
5pub mod uefi;
6pub mod serial;
7pub mod gop;
8pub mod font; 5pub mod font;
9pub mod ps2; 6pub mod gop;
10pub mod interrupts; 7pub mod interrupts;
11pub mod memory; 8pub mod memory;
9pub mod ps2;
10pub mod serial;
11pub 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) {
346 (0x1D, true) => set_mod(state, MOD_RCTRL, pressed), 346 (0x1D, true) => set_mod(state, MOD_RCTRL, pressed),
347 (0x38, false) => set_mod(state, MOD_LALT, pressed), 347 (0x38, false) => set_mod(state, MOD_LALT, pressed),
348 (0x38, true) => set_mod(state, MOD_RALT, pressed), 348 (0x38, true) => set_mod(state, MOD_RALT, pressed),
349 (0x3A, false) 349 (0x3A, false) if pressed => {
350 if pressed => { 350 state.modifiers ^= MOD_CAPS;
351 state.modifiers ^= MOD_CAPS; 351 }
352 }
353 _ => {} 352 _ => {}
354 } 353 }
355} 354}
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/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
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 @@
1#!/usr/bin/env bash
2# =============================================================================
3# tools/boot-image.sh — Create a bootable disk image from the ESP directory
4#
5# Produces a raw disk image (bootable via UEFI) for dd-ing to a USB stick
6# or attaching to QEMU as a hard disk.
7#
8# Usage:
9# ./tools/boot-image.sh [output.img]
10#
11# Default output: raisernics.img
12# =============================================================================
13set -euo pipefail
14
15SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
16cd "$SCRIPT_DIR"
17
18OUTPUT="${1:-raisernics.img}"
19ESP_DIR="${ESP_DIR:-esp}"
20MBR_SZ=1 # 1 MB reserved at start for GPT/pmbr
21SECTOR_SZ=512
22
23# Rebuild ESP if stale
24make all
25
26if [ ! -d "$ESP_DIR" ]; then
27 echo "ERROR: ESP directory '$ESP_DIR' not found. Run 'make all' first."
28 exit 1
29fi
30
31# Calculate required size: ESP contents + MBR gap + some slack
32ESP_SIZE_MB=$(du -sm "$ESP_DIR" 2>/dev/null | cut -f1 || echo 1)
33TOTAL_MB=$((ESP_SIZE_MB + MBR_SZ + 1)) # +1 MB slack
34
35echo "Creating ${TOTAL_MB} MB disk image: ${OUTPUT}"
36
37# Create empty image with MBR gap
38dd if=/dev/zero of="$OUTPUT" bs=1M count="$TOTAL_MB" status=none 2>/dev/null
39
40# Partition table: single GPT partition, type EFI System (C12A7328-F81F-11D2-BA4B-00A0C93EC93B)
41sgdisk --clear \
42 --new=1:${MBR_SZ}M:0 \
43 --typecode=1:C12A7328-F81F-11D2-BA4B-00A0C93EC93B \
44 --change-name=1:"raisernics" \
45 "$OUTPUT" >/dev/null
46
47# Find partition offset
48PART_START=$(sgdisk --info=1 "$OUTPUT" 2>/dev/null | grep "Partition start sector" | awk '{print $NF}')
49if [ -z "$PART_START" ]; then
50 PART_START=$((MBR_SZ * 1024 * 1024 / SECTOR_SZ))
51fi
52
53# Format as FAT32
54mformat -i "$OUTPUT"@$((PART_START * SECTOR_SZ)) -h 32 -s 32 -t "$((TOTAL_MB * 2))" >/dev/null 2>&1 || true
55
56# Copy the ESP contents onto the partition
57mcopy -i "$OUTPUT"@$((PART_START * SECTOR_SZ)) -s "$ESP_DIR"/* ::/ 2>/dev/null
58
59echo " -> ${OUTPUT} ($(ls -lh "$OUTPUT" | awk '{print $5}'))"
60echo ""
61echo "To write to USB: sudo dd if=${OUTPUT} of=/dev/sdX bs=4M status=progress"
62echo "To test with QEMU: qemu-system-x86_64 -bios <OVMF> -drive file=${OUTPUT},format=raw"