Files
firmware/docs/hardware-testing.md
T
Oleksandr Shyshatskyi ff7204f7d5 Run everything in Docker; test against the printer's real busybox
The stock kernel-*.tar.xz turned out to contain rootfs.squashfs -- the
printer's genuine root filesystem. Unpacking it answered several questions
that were previously guesswork:

- init is busybox init -> /etc/init.d/rcS -> S99factory_test_shell ->
  /usr/prog/app_startup.sh. There is no systemd, and rcS runs from the
  read-only squashfs before /usr/prog/etc is bind-mounted over /etc, so a
  new S-script cannot be injected into the stock boot sequence.
- /usr/sbin/dropbear and an ENABLED /etc/init.d/S50dropbear already ship.
  Port 22 is open on a stock printer; only the root password is missing.
  The dropbear cross-build is therefore deleted -- it was never needed.

New: test/test-ash-conformance.sh parses every on-printer script with the
printer's own busybox 1.31.1 ash under qemu-mipsel. A parse error in the
firmwareExe wrapper would mean a blank screen, and neither bash -n nor dash
-n proves busybox accepts it.

Makefile now runs every target inside the pinned build image, with the docker
socket mounted so test targets can start sibling containers. The repo is
mounted at its real host path rather than /src, because sibling mounts are
resolved by the host daemon.

78 checks pass.
2026-08-22 22:02:11 +03:00

6.4 KiB

Hardware testing: the flash ladder

CI proves the package is well-formed and that the installer does not brick a simulated printer. It cannot prove anything about your actual machine. This is the on-hardware procedure, ordered so that each step is recoverable using what the previous step established.

Rule: never skip a rung. Each one exists because it makes the next one recoverable.


Before the first flash

  • Build the uninstall stick and keep it physically separate: make uninstall-pkg → put Creator5*-uninstall.tgz on a spare USB stick.
  • Note your printer's serial number (Settings → About). The factory image restores a placeholder serial and you may need to put yours back.
  • Confirm you can reach the printer's IP.
  • make test passes (78 checks).
  • make rootfs && make test-ash passes — this parses every script that will run on the printer using the printer's own busybox ash.

Two USB sticks, FAT32, both packages at the root of the stick (not in a folder). Ship both filenames (Creator5-* and Creator5Pro-*): the Pro's boot script globs Creator5Pro-*.tgz, the non-Pro globs Creator5-*.tgz.


Stage 0 — probe (make probe)

Changes nothing. Reinstalls the stock software component byte-for-byte and writes a diagnostic report to the USB stick.

Flash it, wait for the reboot, pull the stick and read:

File on the stick What it tells you
anvil-report.txt free space, partitions, installed versions, init layout, whether nginx/moonraker really exist
anvil-stock-etc.tar the whole /etc, so the init chain can be studied offline
anvil-stock-nginx.conf the stock nginx config (not shipped in any update package)
anvil-stock-bootscripts.tar app_startup.sh, start.sh, passwd, shadow as they exist on YOUR unit

Go/no-go: the report exists and the printer boots normally. If the stick comes back empty, the package never installed — nothing was changed, and you have learned that before risking anything.

Check in the report:

  • free space on /usr/data is comfortably above the size of your full package
  • moonrakerDmn: yes and nginx binary: yes
  • the INIT SYSTEM block matches expectations (busybox init, /etc/init.d/rcS, S50dropbear present)

Stage 1 — ssh (make ssh)

Sets a root password you know. Nothing else changes.

This works because the stock rootfs already ships /usr/sbin/dropbear and an enabled /etc/init.d/S50dropbear — port 22 is already open on a stock printer, there is simply no published password.

Set one first:

openssl passwd -6 'your-password'      # paste into ROOT_PW_HASH in config.env

Go/no-go:

ssh root@PRINTER
  • you get a shell
  • the printer still prints normally

From here on you have a real recovery channel, which is what makes every later stage safe.


Stage 2 — web (make web)

Starts nginx (Mainsail on :80) and moonraker (:7125). Klipper and the touchscreen stay stock, so printing behaviour is unchanged.

Go/no-go:

  • http://PRINTER/ loads Mainsail
  • Mainsail shows the printer as ready (not "Klipper reports: ERROR")
  • the touchscreen still works
  • a small test print completes from the touchscreen

If Mainsail loads but Klipper errors, stop here and read /usr/data/logs/printer.log over ssh. Do not continue.


Stage 3 — full (make full)

Replaces the Klipper tree with the fork and installs the toolchanger extras. This is the first stage that changes how the machine moves.

Before flashing, re-read the warnings in creator5-toolchange/README.md about Z offsets. A wrong offset drives the nozzle into the plate.

Go/no-go — with the emergency stop within reach:

  • Klipper starts (ssh root@PRINTER 'grep -i error /usr/data/logs/printer.log | tail')
  • TOOLCHANGE_STATUS responds in the Mainsail console
  • home all axes — watch the first Z move
  • one tool change, by hand, at temperature
  • a single-tool test print
  • a multi-tool test print

The .cfg includes are not wired up automatically — a tuned printer.cfg is never modified. New files arrive as *.mod-new. Add the includes by hand in the order given in the toolchanger README, then run FF_IMPORT_FIRMWARE_CONFIG once.


Stage 4 — helix (make helix)

HelixScreen replaces FlashForge's firmwareExe as the touchscreen UI.

This is the stage where the stock UI stops driving the screen, so understand the safety net before flashing:

  • The genuine binary is kept on disk as firmwareExe.stock and is the fallback. Nothing is deleted.
  • init.d/S70klipper owns Klipper startup, because on stock firmware it was firmwareExe — not any init script — that ran /usr/prog/klipper/start.sh. Without this the printer would boot to a working screen and be unable to move.
  • If the UI dies repeatedly, SAFE-MODE latches after 3 boots and the printer falls back to the stock UI on its own.

Go/no-go:

  • HelixScreen appears on the touchscreen
  • Klipper is running (Mainsail says ready) — this is the one people miss
  • heaters and motion respond from the touchscreen
  • a test print from the touchscreen

Recovering from a bad UI, in increasing severity:

ssh root@PRINTER
/usr/data/mod/init.d/S80ui status        # what did it choose, and why
touch /usr/data/mod/SAFE-MODE            # force the stock UI on next boot
reboot

If ssh is gone too, flash the uninstall stick.


If something goes wrong

Symptom Do this
Printer boots, screen blank ssh in; touch /usr/data/mod/SAFE-MODE; reboot
No ssh, no screen flash the uninstall stick
Uninstall stick does not help flash a stock FlashForge package
Still broken factory package (Creator5Pro-factory-*.tgz plus the separate Creator5Pro-factory.tar.xz on the same stick; needs 800 MB free)

The mod never creates a mount point named like a mod, specifically so that FlashForge's factory-restore package — which greps the mount table for a known community mod's name and refuses to run when it matches — remains usable as a last resort.

Logs worth reading, all on the data partition and all surviving a reboot:

/usr/data/mod-install.log      what the installer did
/usr/data/logs/mod-boot.log    services + UI choice at each boot
/usr/data/logs/printer.log     klipper
/usr/data/logs/helixscreen.log helixscreen