mirror of
https://github.com/openglow-org/forgefirm.git
synced 2026-09-28 01:01:12 -07:00
image: slot-sized release rootfs, ext4 artifact, fwup, mkfw.sh
The release image now targets the 200 MiB factory eMMC slot: content plus 40 MiB working space, hard build failure past the slot size. The raw ext4 is deployed alongside the wic; scripts/mkfw.sh packs it into a signed .fw with factory-pattern upgrade.a/upgrade.b tasks. fwup 1.16.0 recipe (applies ForgeFIRM and Glowforge-signed archives on device) is installed in both images. Dev images stay SD-sized with a 256 MiB working margin and no ceiling. Verified on the 20260808153331 build: release ext4 180.8 MiB; signed .fw applies byte-exact with fwup 1.16.0 and with the factory's 0.14.2 (raw-format pubkey), and 0.14.2 -V verifies the signature.
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
#!/bin/sh
|
||||
# (C) Copyright 2020-2026
|
||||
# Scott Wiederhold, s.e.wiederhold@gmail.com
|
||||
# https://community.openglow.org
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
# Packs a ForgeFIRM rootfs.ext4 into a fwup .fw archive with the factory
|
||||
# update task layout: upgrade.a / upgrade.b raw-write the rootfs into eMMC
|
||||
# slot p1 / p2 (fwup is invoked with -d /dev/mmcblk2p<N>, so offsets are
|
||||
# partition-relative, exactly like the factory updater).
|
||||
#
|
||||
# Usage: mkfw.sh <rootfs.ext4> <version> <output.fw> [private-key]
|
||||
# FWUP=<path> overrides the fwup binary (any 1.x; archives verified to
|
||||
# apply with the factory's fwup 0.14.2).
|
||||
# Unsigned output (no key) is for dev only: release and updater paths
|
||||
# require a signature.
|
||||
|
||||
set -e
|
||||
|
||||
FWUP="${FWUP:-fwup}"
|
||||
ROOTFS="$1"
|
||||
VERSION="$2"
|
||||
OUT="$3"
|
||||
KEY="$4"
|
||||
|
||||
usage () {
|
||||
echo "usage: mkfw.sh <rootfs.ext4> <version> <output.fw> [private-key]" >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
[ -n "$ROOTFS" ] && [ -n "$VERSION" ] && [ -n "$OUT" ] || usage
|
||||
[ -f "$ROOTFS" ] || { echo "ERROR: rootfs '$ROOTFS' not found" >&2; exit 1; }
|
||||
command -v "$FWUP" >/dev/null || { echo "ERROR: fwup not found (set FWUP=)" >&2; exit 1; }
|
||||
|
||||
# The rootfs must fit the 200 MiB factory slot (409600 x 512-byte blocks).
|
||||
SLOT_BYTES=209715200
|
||||
SIZE=$(wc -c < "$ROOTFS")
|
||||
[ "$SIZE" -le "$SLOT_BYTES" ] || {
|
||||
echo "ERROR: rootfs is $SIZE bytes; slot holds $SLOT_BYTES" >&2; exit 1; }
|
||||
|
||||
WORK=$(mktemp -d)
|
||||
trap 'rm -rf "$WORK"' EXIT
|
||||
cp "$ROOTFS" "$WORK/rootfs.ext4"
|
||||
|
||||
cat > "$WORK/fwup.conf" <<EOF
|
||||
meta-product = "ForgeFIRM firmware"
|
||||
meta-description = "ForgeFIRM firmware for Glowforge brand CNC lasers"
|
||||
meta-version = "${VERSION}"
|
||||
meta-platform = "glowforge"
|
||||
meta-architecture = "arm"
|
||||
meta-author = "OpenGlow"
|
||||
|
||||
file-resource rootfs.ext4 {
|
||||
host-path = "${WORK}/rootfs.ext4"
|
||||
}
|
||||
|
||||
task upgrade.a {
|
||||
require-unmounted-destination = true
|
||||
verify-on-the-fly = true
|
||||
on-resource rootfs.ext4 { raw_write(0) }
|
||||
}
|
||||
|
||||
task upgrade.b {
|
||||
require-unmounted-destination = true
|
||||
verify-on-the-fly = true
|
||||
on-resource rootfs.ext4 { raw_write(0) }
|
||||
}
|
||||
EOF
|
||||
|
||||
"$FWUP" -c -f "$WORK/fwup.conf" -o "$WORK/unsigned.fw"
|
||||
|
||||
if [ -n "$KEY" ]; then
|
||||
[ -f "$KEY" ] || { echo "ERROR: key '$KEY' not found" >&2; exit 1; }
|
||||
"$FWUP" -S -s "$KEY" -i "$WORK/unsigned.fw" -o "$OUT"
|
||||
PUB="${KEY%.priv}.pub"
|
||||
if [ -f "$PUB" ]; then
|
||||
"$FWUP" -V -i "$OUT" -p "$PUB" || { echo "ERROR: signature self-check failed" >&2; exit 1; }
|
||||
fi
|
||||
echo "signed: $OUT"
|
||||
else
|
||||
cp "$WORK/unsigned.fw" "$OUT"
|
||||
echo "UNSIGNED (dev only): $OUT"
|
||||
fi
|
||||
|
||||
"$FWUP" -m -i "$OUT" | head -4
|
||||
Reference in New Issue
Block a user