Files
LithosAnanake/scripts/mkdiskimage.sh
T
rajamesandJunie a8b70e88d3 Reorganize source tree: kernel/, v3/, v4/ split and board infrastructure
Source tree reorganization:
- Move StarForth v3 engine to v3/ (src/, include/, Makefile)
- Move kernel to kernel/ (src/, include/, linker/, Makefile)
- Create v4/ skeleton for F18-ISA golden model (DECOMPOSITION.md, JUSTIFICATION.md)
- Move FABRIC-0..4.md to docs/fabric/
- Move ONTOLOGY.md and ROADMAP.md to docs/

Board infrastructure:
- Add boards/ser5/, boards/raspi/, boards/milkv/, boards/zynq7020/
- Each board has board.mk (ISA, CPU flags, boot recipe) and README.md
- Root Makefile becomes thin dispatcher: boot_image, all, clean, docs take TARGET
- make boot_image TARGET=SER5|RASPI|MILKV builds one GPT/MBR image per board
- ZYNQ7020 target exists but stops with clear error (ARMv7 port not built yet)
- scripts/mkdiskimage.sh builds disk images for all boards

Docs pipeline:
- docs/book/ with LaTeX master (main.tex) and Makefile
- pandoc converts Markdown to LaTeX at build time
- Two Lua filters: table-widths.lua (wide tables wrap), code-breaks.lua (inline code breaks)
- make docs builds single PDF (754 pages, 0 missing characters)
- make docs TARGET=<board> adds board appendix
- build/docs/<book|board>/meta.tex stamps git commit into PDF

Bug fixes:
- 42 include paths that only worked by accident now use correct relative paths
- clang-18 hardcode replaced with configurable CC variable (fixed aarch64 build)
- Pi 5: kernel_2712.img linked at 0x80000, .bss zeroed, memory reserved
- Doxyfile, .clang-tidy, README.md, Kconfig paths updated

Verified:
- Hosted v3 build passes 1012 tests, 0 failures
- SER5 image boots in QEMU (OVMF), POST passes, K exact (65536 = Q48_ONE)
- Milk-V image boots in QEMU (OpenSBI + U-Boot + bootefi), POST passes
- make clean TARGET=<board> removes only that board and its ISA objects
- make all builds all boards, hosted v3, and docs in one run

Co-authored-by: Junie <junie@jetbrains.com>
2026-10-01 15:40:09 -04:00

92 lines
3.4 KiB
Bash

#!/usr/bin/env bash
# mkdiskimage.sh -- build a single-partition FAT32 boot disk image.
#
# Used by `make boot_image TARGET=<board>` (kernel/Makefile). One script for
# every board so the geometry rules live in one place:
# - partition 1 starts at 1 MiB (sector 2048) and runs to the last usable
# sector; the FAT32 filesystem is sized to the partition exactly (a
# larger filesystem overruns the partition -- the bug that made early
# SER5 thumbdrive images unbootable, see kernel/Makefile `thumbdrive`);
# - GPT tables reserve 33 sectors at the end of the disk for the backup
# header, MBR tables do not.
#
# Usage:
# mkdiskimage.sh --out IMG --table gpt|mbr --size-mib N --label LABEL \
# SRC:DEST [SRC:DEST ...]
#
# --table gpt -> partition type "EFI System" (UEFI firmware, U-Boot bootefi)
# --table mbr -> partition type 0x0c FAT32 (LBA) (Raspberry Pi firmware)
# DEST is an absolute path inside the FAT filesystem; parent directories are
# created as needed.
#
# Needs only sfdisk (util-linux), mkfs.fat (dosfstools) and mtools -- no
# root, no loop devices.
set -euo pipefail
OUT="" TABLE="" SIZE_MIB="" LABEL=""
while [ $# -gt 0 ]; do
case "$1" in
--out) OUT="$2"; shift 2 ;;
--table) TABLE="$2"; shift 2 ;;
--size-mib) SIZE_MIB="$2"; shift 2 ;;
--label) LABEL="$2"; shift 2 ;;
--) shift; break ;;
-*) echo "mkdiskimage.sh: unknown option $1" >&2; exit 2 ;;
*) break ;;
esac
done
[ -n "$OUT" ] && [ -n "$TABLE" ] && [ -n "$SIZE_MIB" ] && [ -n "$LABEL" ] || {
echo "mkdiskimage.sh: --out, --table, --size-mib and --label are required" >&2; exit 2; }
[ $# -gt 0 ] || { echo "mkdiskimage.sh: no SRC:DEST files given" >&2; exit 2; }
for tool in sfdisk mkfs.fat mmd mcopy; do
command -v "$tool" >/dev/null 2>&1 || PATH="$PATH:/usr/sbin:/sbin"
command -v "$tool" >/dev/null 2>&1 || {
echo "mkdiskimage.sh: $tool not found (install util-linux, dosfstools, mtools)" >&2; exit 1; }
done
TOTAL_SECTORS=$(( SIZE_MIB * 2048 ))
START=2048
case "$TABLE" in
gpt) LAST=$(( TOTAL_SECTORS - 34 )); PTYPE="C12A7328-F81F-11D2-BA4B-00A0C93EC93B" ;;
mbr) LAST=$(( TOTAL_SECTORS - 1 )); PTYPE="c" ;;
*) echo "mkdiskimage.sh: --table must be gpt or mbr" >&2; exit 2 ;;
esac
PART_SECTORS=$(( LAST - START + 1 ))
ESP="$OUT.part1"
rm -f "$OUT" "$ESP"
mkdir -p "$(dirname "$OUT")"
truncate -s $(( TOTAL_SECTORS * 512 )) "$OUT"
if [ "$TABLE" = gpt ]; then
printf 'label: gpt\nstart=%d, size=%d, type=%s, name="EFI System"\n' \
"$START" "$PART_SECTORS" "$PTYPE" | sfdisk --quiet "$OUT"
else
printf 'label: dos\nstart=%d, size=%d, type=%s, bootable\n' \
"$START" "$PART_SECTORS" "$PTYPE" | sfdisk --quiet "$OUT"
fi
truncate -s $(( PART_SECTORS * 512 )) "$ESP"
mkfs.fat -F 32 -n "$LABEL" "$ESP" >/dev/null
for spec in "$@"; do
src="${spec%%:*}"
dest="${spec#*:}"
[ -f "$src" ] || { echo "mkdiskimage.sh: missing input $src" >&2; rm -f "$OUT" "$ESP"; exit 1; }
dir="$(dirname "$dest")"
path=""
IFS=/ read -r -a parts <<< "${dir#/}"
for p in "${parts[@]}"; do
[ -n "$p" ] || continue
path="$path/$p"
mmd -D s -i "$ESP" "::$path" 2>/dev/null || true
done
mcopy -o -i "$ESP" "$src" "::$dest"
done
dd if="$ESP" of="$OUT" bs=512 seek="$START" conv=notrunc status=none
rm -f "$ESP"
echo " IMAGE $OUT ($TABLE, ${SIZE_MIB} MiB, FAT32 '$LABEL')"