WORK IN PROGRESS: MANY FEATURES MAY BE BROKEN. This has not been
verified to boot real Wyse 3040 hardware end-to-end yet (see
Known limitations). Test it in a VM before you
image real units, and expect to fix things.
Source-available · Non-commercial — see Licence below.
Builds a bootable USB installer that wipes a Wyse 3040's internal eMMC and
leaves it running a headless Debian 12 appliance with Klipper + Moonraker +
a web UI (Mainsail or Fluidd), WiFi (hotspot or station mode), and a working
ethernet port. Designed for imaging a batch of units one at a time from the
same USB stick.
Screenshots
The GUI (wyse_injector.py — see below):
![]() |
![]() |
| First launch — read this before agreeing | Tab 1: set everything about the build |
![]() |
![]() |
| Tab 2: flash the built ISO onto a USB stick | Tab 3: desktop shortcut, licence, about |
Hardware reality check (Wyse 3040 / N10D)
- CPU: Atom x5-Z8350, 64-bit, 4 core — plenty for klippy + Moonraker.
- RAM: 2GB, soldered, not upgradable on any 3040. This shapes several choices below (no desktop environment, zram instead of a swap partition, a fairly minimal package set).
-
Storage: 8GB (or 16GB on some units) eMMC, soldered, seen as
/dev/mmcblk0normally. A minimal Debian + Klipper stack lands around 1.5–2GB installed, so 8GB is comfortable, not tight. -
Boot quirk: the 3040's UEFI firmware does not reliably persist normal
boot-entry (NVRAM) registrations — this is a documented issue in the
Wyse-3040 hobbyist community, not something specific to this installer.
If GRUB is installed the normal way, the unit can come up with no boot
device found. The fix, baked into
preseed.cfg, is to force GRUB onto the EFI removable media fallback path (grub-installer/force-efi-extra-removable), which is exactly the documented Debian workaround for "broken UEFI firmware." -
WiFi: the factory-fit module (when present — many surplus/refurbished
units ship without it, since it's a socket option) is a Marvell 8897 on
an M.2 SDIO card. Its Linux AP-mode driver support (
mwifiex_sdio) has a real history of BSS-start timeouts and TX hangs in AP mode. Given "AP mode by default" is a hard requirement here, the recommended path is a cheap USB WiFi dongle with a chipset known to be solid inhostapdAP mode (e.g. Realtek RTL8188EUS-based dongles are common and well supported). The config here doesn't care which one you use — anything that shows up aswlan0works, and interface naming is pinned to that (see below). The internal SDIO card will also work as a best-effort fallback if that's all you have, just don't be surprised if it occasionally needs asystemctl restart hostapd. -
Ethernet: Realtek RTL8111/8168 Gigabit — supported by the mainline
r8169driver, no firmware blob needed, just works.
Flashing and imaging a unit
Open Balena Etcher, select klipper-wyse3040-installer.iso, select
your USB stick, flash. (Command-line dd works too, if you'd rather:
sudo dd if=klipper-wyse3040-installer.iso of=/dev/sdX bs=4M status=progress conv=fsync.)
Per unit:
- Plug the USB stick in, plug ethernet into a switch/router with
internet access (needed once, during provisioning, to
git cloneKlipper/Moonraker andapt installpackages — this is separate from the AP-mode/ethernet-fallback behavior the finished system has). - Power on, boot from USB (Wyse 3040 boot-menu key is usually F12/Esc at POST — check yours).
- Walk away — it's fully unattended and wipes the eMMC without asking. A single unit should take roughly 10–20 minutes depending on your link speed (base install + package downloads + git clones + pip installs).
- It reboots into the finished appliance automatically. Remove the USB stick for the next unit.
Using a finished unit
- Join the
Klipper-XXXXXXWiFi network (see it printed at the end oflate-command.sh's log, or just look for it), then browse tohttp://192.168.7.1. - Or plug ethernet into your LAN/PC and browse to
http://klipper-xxxxxx.local(or find its DHCP-assigned IP from your router). - Fill in
~print/printer_data/config/printer.cfgfor your actual printer board via the Mainsail file editor — this ships empty since it's machine-specific. Your printer's MCU normally shows up under/dev/serial/by-id/...once plugged into one of the 3040's USB ports.
The KlipPlug option (experimental)
KlipPlug is a separate project
by the same author: a plugin manager for Klipper that can run many OctoPrint
plugins. Tick KlipPlug on the Build tab (or run KLIPPLUG=1 ./setup.sh,
or set a KLIPPLUG repo secret to 1 for the GitHub Actions build) and
every unit imaged from that ISO gets it as its own service. Its page is at
http://<unit>:7130, next to Mainsail or Fluidd, which are not changed.
-
Where units get it from: if a
klipplugfolder or aklipplug….zipsits next towyse_injector.py/setup.shwhen you build, that copy is baked into the ISO and units need no download for it. Otherwise each unit clones it from GitHub during its install. (The GitHub Actions build has no local copy, so its units always download.) -
If a unit can't get it or can't install it, that unit's install still
completes without it.
/etc/wyse-klipper-optionsandhttp://<unit>/diagnostics.txton the unit say whether it's there. -
Updates: this installer's
moonraker.confhas no update manager, so KlipPlug is not updated from the web UI. Update it on the unit withcd ~/klipplug && git pull && sudo systemctl restart klipplug(only when it came from GitHub; a baked-in copy has no git history). - What has and hasn't been tried: the build-side code (baking a local copy into the installer and packing it) and the install step were run on a PC against a stand-in for the freshly installed system (a chroot). It has not been run inside a real Debian installer or on a real Wyse 3040, like the rest of this project. KlipPlug itself is work in progress and has not been run on a physical printer.
- Licence: KlipPlug is under AGPL-3.0, not this tool's licence. See THIRD_PARTY.md.
Not an actual hardware photo
To be clear: that's pastry, not a Wyse 3040 — a bit of fun, not a product
shot. See Known limitations above for what this
project has and hasn't actually been tested on.





Top comments (1)
tr.ee/dev-to