mirror of
https://github.com/Klipper4FlashForge/firmware.git
synced 2026-10-22 05:12:16 -05:00
Builds a modified FlashForge update package that the printer installs by itself from a USB stick, reusing FlashForge's own updater rather than a parallel one. Integration is a single file: /usr/prog/PROGRAM/software/firmwareExe is replaced with a shell script. Everything funnels through that binary, so app_startup.sh, rcS and the init chain stay completely stock. The genuine binary is kept as firmwareExe.stock and remains the default UI. Key findings from the stock firmware, each enforced by a test: - components named *.tar.xz are PLAIN tar; the installer runs bare `tar -xvf` - the .tgz is DES3-encrypted plain tar, not gzip - nothing in init starts Klipper -- firmwareExe runs start.sh, so replacing the UI without S70klipper leaves a printer that cannot move - the installer wipes the software dir before run.sh, so an uninstall package must ship the genuine firmwareExe rather than back one up - ssh already works: stock ships dropbear + an enabled S50dropbear, only the root password is missing Brick-safety is designed in, not bolted on: a five-rung profile ladder starting with a probe that changes nothing, a container-based simulation that actually runs the installer and asserts the printer would still boot, an uninstall round-trip test, and a SAFE-MODE latch for UI crash loops. 75 checks pass. Not yet run on hardware.
76 lines
3.0 KiB
Bash
76 lines
3.0 KiB
Bash
#!/bin/sh
|
|
# /usr/prog/PROGRAM/software/firmwareExe -- REPLACED by the mod.
|
|
#
|
|
# The stock boot chain is:
|
|
# busybox init -> /etc/init.d/rcS -> S99factory_test_shell
|
|
# -> /usr/prog/app_startup.sh -> firmwareExe
|
|
# and firmwareExe itself is what launches "/usr/prog/klipper/start.sh &".
|
|
#
|
|
# Because everything funnels through this one path, replacing this binary
|
|
# with a script is the cleanest possible integration point: app_startup.sh,
|
|
# rcS and the whole init chain stay 100% STOCK and are never patched.
|
|
#
|
|
# The original binary is preserved next to us as firmwareExe.stock and is
|
|
# still the default UI; nothing is lost by installing the mod.
|
|
#
|
|
# Two further properties we get for free:
|
|
# * app_startup.sh's own watchdog greps `ps` for "firmwareExe" 5s after
|
|
# launch. This script keeps that name (it IS $0) and stays in the
|
|
# FOREGROUND, so the stock watchdog supervises the mod correctly.
|
|
# * If this script is ever removed, app_startup.sh restores a firmwareExe
|
|
# from the newest version directory -- the stock recovery path still works.
|
|
|
|
MODDIR=/usr/data/mod
|
|
SELFDIR=`dirname "$0"`
|
|
STOCK_UI="$SELFDIR/firmwareExe.stock"
|
|
|
|
[ -f $MODDIR/mod.conf ] && . $MODDIR/mod.conf
|
|
mkdir -p /usr/data/logs
|
|
exec >>/usr/data/logs/mod-boot.log 2>&1
|
|
echo "=== mod firmwareExe `date 2>/dev/null` (UI=${MOD_UI:-stock}) ==="
|
|
|
|
# ---- services ------------------------------------------------------------
|
|
# init.d-style scripts, run in filename order. One failing service must never
|
|
# stop the rest: Klipper has to come up even if the web stack is broken.
|
|
if [ -d $MODDIR/init.d ]; then
|
|
for s in $MODDIR/init.d/S*; do
|
|
[ -x "$s" ] || continue
|
|
echo "--- `basename $s` ---"
|
|
"$s" start || echo "`basename $s`: returned $?"
|
|
done
|
|
fi
|
|
|
|
# ---- the UI, in the foreground so the stock watchdog can see us ----------
|
|
# S80ui already handled SAFE-MODE, crash counting and fallback selection and
|
|
# wrote its verdict here.
|
|
UI_CHOICE=`cat $MODDIR/.ui-choice 2>/dev/null || echo stock`
|
|
echo "ui: running $UI_CHOICE in the foreground"
|
|
|
|
case "$UI_CHOICE" in
|
|
helix)
|
|
HELIX_DATA_DIR=$MODDIR/helixscreen
|
|
HELIX_LOG_DEST=file
|
|
HELIX_LOG_FILE=/usr/data/logs/helixscreen.log
|
|
export HELIX_DATA_DIR HELIX_LOG_DEST HELIX_LOG_FILE
|
|
if [ -x $MODDIR/helixscreen/bin/helix-launcher.sh ]; then
|
|
$MODDIR/helixscreen/bin/helix-launcher.sh
|
|
else
|
|
$MODDIR/helixscreen/bin/helix-screen
|
|
fi
|
|
;;
|
|
*)
|
|
if [ -x "$STOCK_UI" ]; then
|
|
exec "$STOCK_UI"
|
|
else
|
|
echo "ui: firmwareExe.stock missing -- staying alive headless so ssh keeps working"
|
|
while true; do sleep 3600; done
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
# If the UI exits we do NOT exit: dropping out of this script makes
|
|
# app_startup.sh think the UI died and re-exec us, which would restart every
|
|
# service. Hold the process instead; ssh and Mainsail remain available.
|
|
echo "ui: $UI_CHOICE exited -- holding process so services stay up"
|
|
while true; do sleep 3600; done
|