mirror of
https://github.com/Klipper4FlashForge/firmware.git
synced 2026-10-23 13:52:16 -05:00
The audit branch was cut from origin/master and so was missinga40bc86("Ship our own Moonraker") and3e997e5(HelixScreen v0.99.115-creator5.1). Merging it as-is would have reverted both. Rebased onto master; three conflicts resolved by keeping master's Moonraker code and applying the audit's comment corrections around it (bin/common.sh, bin/verify.sh, test/integration/printer/case-install.sh). Two findings were stale against that commit and are re-checked here: * docs/building.md listed four BUILD_* flags; there are five. BUILD_MOONRAKER was added bya40bc86and never reached the doc -- the same class of drift this branch exists to remove, caught only because the rebase surfaced it. * the default package size is ~63MB, not the ~62MB measured before Moonraker rode along. Measured again on a real build: 65,720,344 bytes. Also folded in: the three-asset wording for MAINSAIL_ZIP / HELIX_TGZ / MOONRAKER_TGZ keeps master's list and the audit's correction that an explicit path IS checksummed and overwritten. Full suite on the rebased tree: 12 passed, 0 failed, 0 skipped -- including all five moonraker assertions, so the feature survived the merge intact. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
144 lines
6.3 KiB
Bash
Executable File
144 lines
6.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# 3/3 -- repack work/software back into an installable USB package.
|
|
#
|
|
# ./bin/pack.sh software component + the mod payload (DEFAULT, ~63MB)
|
|
# ./bin/pack.sh --full also carry kernel / control / library
|
|
# ./bin/pack.sh --plain no encryption: emits runFirmwareExe.sh + payload
|
|
# for the /mnt/runFirmwareExe.sh dev path
|
|
#
|
|
# Slim is the default because the stock installer skips any component that is
|
|
# absent: every update_<name> guards on `ls -1t <name>-*.tar.xz` and returns
|
|
# early when it fails. So shipping only the component we actually modified
|
|
# leaves the kernel, the rootfs image and the MCU/board firmware completely
|
|
# untouched -- MCU flashing is the riskiest thing in the package and there is
|
|
# no reason to run it to install a userspace mod.
|
|
#
|
|
# (start.img, end.img and play are still shipped: runFirmwareExe.sh uses those
|
|
# unconditionally.)
|
|
set -euo pipefail
|
|
. "$(dirname "$0")/common.sh"
|
|
|
|
SLIM=1; PLAIN=0
|
|
for a in "$@"; do
|
|
case "$a" in
|
|
--full) SLIM=0 ;;
|
|
--slim) SLIM=1 ;; # accepted for compatibility; now the default
|
|
--plain) PLAIN=1 ;;
|
|
*) echo "unknown option: $a" >&2; exit 1 ;;
|
|
esac
|
|
done
|
|
|
|
[ -d work/software ] || { echo "run ./bin/unpack.sh first" >&2; exit 1; }
|
|
STOCK_SW_VER=$(cat work/.stock_sw_ver)
|
|
OUT_VER="${SW_VER:-$STOCK_SW_VER}"
|
|
|
|
rm -rf work/stage work/out
|
|
mkdir -p work/stage work/out
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 1. md5sum.list -- the installer hard-gates on this. Paths must be "./rel",
|
|
# and the list must not contain itself.
|
|
# ---------------------------------------------------------------------------
|
|
echo ">> regenerating md5sum.list"
|
|
( cd work/software
|
|
rm -f md5sum.list
|
|
find . -type f ! -name md5sum.list -print0 \
|
|
| sort -z \
|
|
| xargs -0 md5sum > md5sum.list
|
|
echo " $(wc -l < md5sum.list) entries" )
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 2. software-<ver>.tar.xz
|
|
#
|
|
# !! NOT actually xz-compressed. FlashForge's own components are PLAIN
|
|
# tar archives that merely carry a .tar.xz name -- verify with
|
|
# `file work/outer/software-*.tar.xz`. The stock installer extracts them
|
|
# with a bare `tar -xvf`, so a genuinely xz-compressed file here does not
|
|
# install. Keep this a plain tar.
|
|
# ---------------------------------------------------------------------------
|
|
echo ">> building software-$OUT_VER.tar.xz (plain tar, matching stock)"
|
|
tar -cf "work/stage/software-$OUT_VER.tar.xz" -C work/software .
|
|
ls -lh "work/stage/software-$OUT_VER.tar.xz" | awk '{print " "$5}'
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 3. the rest of the outer package
|
|
# ---------------------------------------------------------------------------
|
|
# The mod payload: rides in the outer package so it lands on /usr/data,
|
|
# not on the firmware partition.
|
|
if [ -d work/modpayload ]; then
|
|
# This one IS really xz: we extract it ourselves with `xz -dc`, and
|
|
# FlashForge's factory installer proves xz exists on the printer.
|
|
echo ">> compressing anvil.tar.xz (Mainsail / HelixScreen / Moonraker / bin)"
|
|
tar -cf - -C work/modpayload . | xz -T0 -6 > work/stage/anvil.tar.xz
|
|
ls -lh work/stage/anvil.tar.xz | awk '{print " "$5}'
|
|
fi
|
|
|
|
# FlashForge's own installer, reused verbatim -- it already does the whole
|
|
# USB auto-install dance. We only change what it installs.
|
|
cp -f work/outer/runFirmwareExe.sh work/stage/
|
|
chmod +x work/stage/runFirmwareExe.sh
|
|
for f in start.img end.img play; do
|
|
[ -f "work/outer/$f" ] && cp -f "work/outer/$f" work/stage/
|
|
done
|
|
if [ "$SLIM" = "0" ]; then
|
|
echo ">> --full: also carrying kernel / control / library"
|
|
echo " (this reflashes the kernel and the MCU/board firmware)"
|
|
for f in work/outer/kernel-*.tar.xz work/outer/control-*.tar.xz work/outer/library-*.tar.xz; do
|
|
[ -f "$f" ] && cp -f "$f" work/stage/
|
|
done
|
|
else
|
|
echo ">> slim: software component only -- kernel, rootfs and MCU untouched"
|
|
fi
|
|
echo ">> outer payload:"
|
|
ls -la work/stage | sed 's/^/ /'
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 4. emit
|
|
# ---------------------------------------------------------------------------
|
|
# MOD_VER is the release date; common.sh defaults it to today (UTC).
|
|
BASE="${MOD_NAME:-anvil}-${MOD_VER:?}"
|
|
|
|
if [ "$PLAIN" = "1" ]; then
|
|
# app_startup.sh also honours a bare /mnt/runFirmwareExe.sh -- no crypto,
|
|
# no .tgz. Copy the whole work/out/plain/ tree to the USB root.
|
|
mkdir -p work/out/plain
|
|
cp -a work/stage/. work/out/plain/
|
|
echo
|
|
echo "PLAIN package: work/out/plain/ -> copy its CONTENTS to the USB root"
|
|
else
|
|
# Name the output after the model the package is actually for. The two
|
|
# models ship DIFFERENT firmwareExe binaries, so emitting both filenames
|
|
# from one build (as an earlier version did) would hand the wrong
|
|
# firmware to one of them. Each model must be built from its own stock
|
|
# package.
|
|
PKG_MACHINE=$(cat work/.pkg_machine 2>/dev/null || echo "")
|
|
if [ "$PKG_MACHINE" = unknown ]; then PKG_MACHINE=""; fi
|
|
if [ -n "$PKG_MACHINE" ] && [ "$PKG_MACHINE" != "${TARGET_MACHINE:-$PKG_MACHINE}" ]; then
|
|
echo "MODEL MISMATCH: stock package is for '$PKG_MACHINE', TARGET_MACHINE='$TARGET_MACHINE'" >&2
|
|
echo " point STOCK_TGZ_$(echo "$TARGET_MACHINE" | tr a-z A-Z) at a $TARGET_MACHINE package" >&2
|
|
exit 1
|
|
fi
|
|
OUT_MACHINE="${PKG_MACHINE:-${TARGET_MACHINE:-Creator5Pro}}"
|
|
|
|
echo ">> tarring + encrypting"
|
|
# Outer tar is NOT gzipped despite the .tgz name -- unTar pipes the
|
|
# decrypted stream straight into `tar xvf -`.
|
|
# The Pro's app_startup.sh globs /mnt/Creator5Pro-*.tgz and the non-Pro
|
|
# globs /mnt/Creator5-*.tgz, so the filename prefix must match the model.
|
|
OUTFILE="work/out/${OUT_MACHINE}-${BASE}.tgz"
|
|
tar -cf - -C work/stage . \
|
|
| openssl des3 -salt -md md5 -k "$FF_KEY" > "$OUTFILE"
|
|
|
|
echo
|
|
echo "Package:"
|
|
ls -lh "$OUTFILE" | awk '{print " "$9" "$5}'
|
|
echo " installs on: $OUT_MACHINE only"
|
|
echo
|
|
echo "Sanity check (decrypt + list):"
|
|
openssl des3 -d -k "$FF_KEY" -salt -md md5 -in "$OUTFILE" 2>/dev/null \
|
|
| tar -tvf - | sed 's/^/ /'
|
|
echo
|
|
echo "Copy it to the root of a FAT32 USB stick, plug it in, power on."
|
|
echo "Install log afterwards: /usr/data/anvil-install.log"
|
|
fi
|