<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Sovol on mainline Klipper</title><link>https://sovol.lexfrei.dev/</link><description>Recent content on Sovol on mainline Klipper</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://sovol.lexfrei.dev/index.xml" rel="self" type="application/rss+xml"/><item><title>Architecture</title><link>https://sovol.lexfrei.dev/zero/hardware/architecture/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sovol.lexfrei.dev/zero/hardware/architecture/</guid><description>&lt;h1 id="system-architecture"&gt;System architecture&lt;a class="anchor" href="#system-architecture"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;A reference description of the Sovol Zero as shipped, captured from the running machine — host filesystem, Klipper config, MCU runtime, git remotes. It exists to support the migration: knowing exactly what hardware and software is in play, and which pieces are vendor-specific versus stock.&lt;/p&gt;
&lt;p&gt;The Sovol Zero is a CoreXY printer, an industrialised derivative of the Voron 0, with a 150×150×150 mm build volume in a closed frame. It runs Klipper on a Linux host talking to multiple STM32 MCUs over CANbus. Internally Sovol calls it the &amp;ldquo;SV08 mini&amp;rdquo; — the vendor firmware package ships as &lt;code&gt;SV08mini_Update_Package-*.deb&lt;/code&gt;, and it shares its CAN toolhead module with the SV08 Max — though it&amp;rsquo;s sold only as the Sovol Zero.&lt;/p&gt;</description></item><item><title>Building the firmware</title><link>https://sovol.lexfrei.dev/zero/firmware/build/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sovol.lexfrei.dev/zero/firmware/build/</guid><description>&lt;h1 id="building-the-firmware"&gt;Building the firmware&lt;a class="anchor" href="#building-the-firmware"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;The MCU firmware (Katapult + Klipper) can be built either &lt;strong&gt;on the printer&amp;rsquo;s own host&lt;/strong&gt; or &lt;strong&gt;on a Mac / Linux box&lt;/strong&gt;, then the &lt;code&gt;.bin&lt;/code&gt; copied over. Both produce identical images — pick whichever is handy.&lt;/p&gt;
&lt;h2 id="toolchain"&gt;Toolchain&lt;a class="anchor" href="#toolchain"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="on-the-printer-host-the-sovol-zero-boards-allwinner-h616-debian-aarch64"&gt;On the printer host (the Sovol Zero board&amp;rsquo;s Allwinner H616, Debian aarch64)&lt;a class="anchor" href="#on-the-printer-host-the-sovol-zero-boards-allwinner-h616-debian-aarch64"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;arm-none-eabi-gcc&lt;/code&gt; is already installed — it&amp;rsquo;s the vendor&amp;rsquo;s own build chain. Clone the sources and build in place; no extra setup, and none of the macOS quirk below:&lt;/p&gt;</description></item><item><title>Easy install</title><link>https://sovol.lexfrei.dev/zero/os/quickstart/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sovol.lexfrei.dev/zero/os/quickstart/</guid><description>&lt;h1 id="easy-install--for-most-people"&gt;Easy install — for most people&lt;a class="anchor" href="#easy-install--for-most-people"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;The &lt;a href="https://sovol.lexfrei.dev/zero/os/clean-slate/"&gt;clean-slate page&lt;/a&gt; bakes everything into the image offline, by hand. You don&amp;rsquo;t have to. There&amp;rsquo;s a friendlier path: flash a base image, let it come up, and answer a short wizard over SSH — the same first-run experience as any Armbian board. No ext4 editing, no &lt;code&gt;debugfs&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Two facts make this easy on the Zero:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The board has a microSD slot, and the H616 boots SD before eMMC.&lt;/strong&gt; So you can run the whole thing from a microSD — no reader, no pulling the module, no risk to the stock eMMC. Leave the eMMC alone as a factory backup, or &lt;a href="https://sovol.lexfrei.dev/zero/os/in-place/"&gt;move the system onto it later&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The first SSH login runs Armbian&amp;rsquo;s friendly setup wizard&lt;/strong&gt; (&lt;code&gt;armbian-firstlogin&lt;/code&gt;): it makes you change the root password, creates your user, and asks locale + timezone — right there in the SSH session.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Use the &lt;strong&gt;&lt;a href="https://github.com/lexfrei/sovobian/releases"&gt;Sovobian&lt;/a&gt;&lt;/strong&gt; image for all of these — it&amp;rsquo;s upstream Armbian CB1 with the 40 MHz eMMC overlay already baked, and it ships the 6.12.68 kernel where onboard Ethernet works out of the box. A plain BTT CB1 image drives the eMMC at 3× the validated clock (see &lt;a href="https://sovol.lexfrei.dev/zero/os/armbian/#what-almost-a-cb1-actually-means#what-almost-a-cb1-actually-means"&gt;the CB1 difference&lt;/a&gt;) — don&amp;rsquo;t use it.&lt;/p&gt;</description></item><item><title>KIAUH stack</title><link>https://sovol.lexfrei.dev/zero/application/kiauh/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sovol.lexfrei.dev/zero/application/kiauh/</guid><description>&lt;h1 id="the-application-stack-via-kiauh"&gt;The application stack via KIAUH&lt;a class="anchor" href="#the-application-stack-via-kiauh"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Everything above Klipper — Moonraker, Mainsail, Crowsnest — is already stock upstream, so the fastest clean install is &lt;a href="https://github.com/dw-0/kiauh"&gt;dw-0/kiauh&lt;/a&gt;. Clone it and install, in order: &lt;strong&gt;Klipper, Moonraker, Mainsail, Mainsail-Config, Crowsnest.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Point Klipper&amp;rsquo;s host at the same &lt;code&gt;master&lt;/code&gt; checkout your MCUs were built from, with a venv built from its &lt;code&gt;requirements.txt&lt;/code&gt;, and set &lt;code&gt;[update_manager klipper] channel: dev&lt;/code&gt; in &lt;code&gt;moonraker.conf&lt;/code&gt; so it tracks &lt;code&gt;master&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="two-post-install-fixes"&gt;Two post-install fixes&lt;a class="anchor" href="#two-post-install-fixes"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Both come from experience on this board:&lt;/p&gt;</description></item><item><title>Over stock firmware</title><link>https://sovol.lexfrei.dev/zero/runbooks/over-stock/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sovol.lexfrei.dev/zero/runbooks/over-stock/</guid><description>&lt;h1 id="runbook--migrating-in-place-over-the-stock-firmware"&gt;Runbook — migrating in place over the stock firmware&lt;a class="anchor" href="#runbook--migrating-in-place-over-the-stock-firmware"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;The printer works and you migrate on top of it. The vendor OS stays, the application and MCU firmware move to upstream, and the OS is an optional last step. This is the incremental de-vendoring path.&lt;/p&gt;
&lt;p&gt;Each step below is a link into the component that does the work — this page is only the order.&lt;/p&gt;
&lt;h2 id="1-back-up-everything-first"&gt;1. Back up everything first&lt;a class="anchor" href="#1-back-up-everything-first"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Vendor stack rsync, an SWD dump of the toolhead, and ideally a full eMMC image. The backups are what make every later step reversible. → &lt;a href="https://sovol.lexfrei.dev/zero/os/recovery/#back-up-first-the-checklist#back-up-first-the-checklist"&gt;Recovery: back up first&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Flashing over SWD</title><link>https://sovol.lexfrei.dev/zero/firmware/flashing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sovol.lexfrei.dev/zero/firmware/flashing/</guid><description>&lt;h1 id="flashing-over-swd-with-a-flipper-zero-dap-link"&gt;Flashing over SWD with a Flipper Zero (DAP Link)&lt;a class="anchor" href="#flashing-over-swd-with-a-flipper-zero-dap-link"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;The toolhead Katapult is request-only and can&amp;rsquo;t be recovered over CAN once an app is broken, so an SWD probe is the safety net. Any CMSIS-DAP probe works — an ST-Link V2 clone, or a Flipper Zero running the &lt;strong&gt;DAP Link&lt;/strong&gt; app.&lt;/p&gt;
&lt;blockquote class='book-hint warning'&gt;
&lt;p&gt;&lt;strong&gt;Verified scope.&lt;/strong&gt; Everything here was tested only on the &lt;strong&gt;F103 toolhead&lt;/strong&gt;, and only with a &lt;strong&gt;Flipper Zero&lt;/strong&gt; (DAP Link app). An ST-Link should behave the same (it is standard SWD), and the H750 section below is reasoned, not tested. Corrections and additions are welcome — open a PR.&lt;/p&gt;</description></item><item><title>Klipper config</title><link>https://sovol.lexfrei.dev/zero/application/klipper-config/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sovol.lexfrei.dev/zero/application/klipper-config/</guid><description>&lt;h1 id="translating-the-config-to-mainline"&gt;Translating the config to mainline&lt;a class="anchor" href="#translating-the-config-to-mainline"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;The vendor &lt;code&gt;printer.cfg&lt;/code&gt; doesn&amp;rsquo;t run as-is on upstream Klipper — a few sections depend on vendor-only firmware behaviour. Translate these off the vendor config; the rest carries over.&lt;/p&gt;
&lt;h2 id="eddy-on-software-i2c"&gt;Eddy on software I2C&lt;a class="anchor" href="#eddy-on-software-i2c"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The vendor ran the LDC1612 on hardware &lt;code&gt;i2c2&lt;/code&gt;, but only because its F103 firmware carries STM32F1 hardware-I2C errata workarounds that mainline lacks; on mainline, hardware &lt;code&gt;i2c2&lt;/code&gt; throws &lt;code&gt;START_NACK&lt;/code&gt; → shutdown. Use bitbang instead:&lt;/p&gt;</description></item><item><title>Toolhead pinout &amp; SWD</title><link>https://sovol.lexfrei.dev/zero/hardware/toolhead/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sovol.lexfrei.dev/zero/hardware/toolhead/</guid><description>&lt;h1 id="toolhead-pinout--swd-header"&gt;Toolhead pinout &amp;amp; SWD header&lt;a class="anchor" href="#toolhead-pinout--swd-header"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Transcribed from Sovol&amp;rsquo;s official pin definition (&lt;code&gt;Motherboard/Extra_Pin_definition.pdf&lt;/code&gt; in &lt;a href="https://github.com/Sovol3d/SOVOL-ZERO"&gt;Sovol3d/SOVOL-ZERO&lt;/a&gt;) — see that PDF for the full labelled board image. The toolhead MCU is an STM32F103 (&lt;code&gt;extruder_mcu&lt;/code&gt;), board silk &lt;code&gt;MINI-ZJB-V1.0&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="connectors"&gt;Connectors&lt;a class="anchor" href="#connectors"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Connector&lt;/th&gt;
					&lt;th&gt;Pins (as silk-screened)&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Cooling fan&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;24V&lt;/code&gt; · PWM &lt;code&gt;PA6&lt;/code&gt; · FG &lt;code&gt;PA1&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Fan (top)&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;24V&lt;/code&gt; · PWM &lt;code&gt;PA7&lt;/code&gt; · FG &lt;code&gt;PA2&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Model fan&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;24V&lt;/code&gt; · PWM &lt;code&gt;PB0&lt;/code&gt; · FG &lt;code&gt;PA3&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Nozzle thermistor&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;PA5&lt;/code&gt; · &lt;code&gt;GND&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Heating block&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;GND&lt;/code&gt; · &lt;code&gt;24V&lt;/code&gt; · &lt;code&gt;PB1&lt;/code&gt; · &lt;code&gt;GND&lt;/code&gt; · &lt;code&gt;PA4&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Heater&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;24V&lt;/code&gt; · MC_HEATER &lt;code&gt;PB7&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;24 V supply&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;GND&lt;/code&gt; · &lt;code&gt;24V&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Extruder motor&lt;/td&gt;
					&lt;td&gt;DIR &lt;code&gt;PA9&lt;/code&gt; · STEP &lt;code&gt;PA8&lt;/code&gt; · EN &lt;code&gt;PA11&lt;/code&gt; · UART &lt;code&gt;PA12&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;X-axis limit&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;PA10&lt;/code&gt; · &lt;code&gt;GND&lt;/code&gt; · &lt;code&gt;5V&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Limit / sensor&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;5V&lt;/code&gt; · &lt;code&gt;GND&lt;/code&gt; · &lt;code&gt;PC15&lt;/code&gt; · &lt;code&gt;PC14&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Eddy current sensor&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;5V3&lt;/code&gt; · &lt;code&gt;GND&lt;/code&gt; · &lt;strong&gt;&lt;code&gt;PB10&lt;/code&gt; (SCL)&lt;/strong&gt; · &lt;strong&gt;&lt;code&gt;PB11&lt;/code&gt; (SDA)&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Mainboard comm (CAN)&lt;/td&gt;
					&lt;td&gt;CANL · &lt;code&gt;GND&lt;/code&gt; · CANH (CAN_R &lt;code&gt;PB8&lt;/code&gt; · CAN_T &lt;code&gt;PB9&lt;/code&gt;)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;SWD header&lt;/strong&gt; (silk &lt;code&gt;5V3 IO CK G&lt;/code&gt;)&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;5V3&lt;/code&gt; = 3.3 V · &lt;code&gt;IO&lt;/code&gt; = SWDIO (&lt;code&gt;PA13&lt;/code&gt;) · &lt;code&gt;CK&lt;/code&gt; = SWCLK (&lt;code&gt;PA14&lt;/code&gt;) · &lt;code&gt;G&lt;/code&gt; = GND&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The eddy sensor connector exposes &lt;code&gt;PB10&lt;/code&gt;/&lt;code&gt;PB11&lt;/code&gt;. On mainline Klipper drive the LDC1612 over &lt;strong&gt;software I2C&lt;/strong&gt; on those pins, not hardware &lt;code&gt;i2c2&lt;/code&gt; — see &lt;a href="https://sovol.lexfrei.dev/zero/application/klipper-config/"&gt;the Klipper config page&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Vanilla Armbian</title><link>https://sovol.lexfrei.dev/zero/os/armbian/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sovol.lexfrei.dev/zero/os/armbian/</guid><description>&lt;h1 id="vanilla-armbian-on-the-sovol-zero-board"&gt;Vanilla Armbian on the Sovol Zero board&lt;a class="anchor" href="#vanilla-armbian-on-the-sovol-zero-board"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;The Klipper migration leaves Sovol&amp;rsquo;s stock OS image untouched — Klipper lives in &lt;code&gt;/home/sovol&lt;/code&gt;, so swapping the Klipper layer never rewrites the rootfs or the bootloader. For a fully vendor-free machine the last layer is the OS on the eMMC. This is the harder, destructive step (it rewrites the whole boot device).&lt;/p&gt;
&lt;p&gt;This is a verified end-to-end recipe for &lt;strong&gt;vanilla Armbian on the stock 8 GB eMMC module&lt;/strong&gt; — no custom OS build, no replacement module. The original Armbian-on-Zero walkthrough is &lt;a href="https://github.com/asnajder/zero-config"&gt;asnajder/zero-config&lt;/a&gt;, which this builds on; where the two disagree (most notably on the 8 GB module), the difference is explained below.&lt;/p&gt;</description></item><item><title>With an eMMC reader</title><link>https://sovol.lexfrei.dev/zero/runbooks/emmc-reader/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sovol.lexfrei.dev/zero/runbooks/emmc-reader/</guid><description>&lt;h1 id="runbook--clean-slate-build-with-an-emmc-reader"&gt;Runbook — clean-slate build with an eMMC reader&lt;a class="anchor" href="#runbook--clean-slate-build-with-an-emmc-reader"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;The path a recovery or a fresh build actually takes: OS first, application on top, MCUs usually last — and often untouched, because &lt;a href="https://sovol.lexfrei.dev/concepts/"&gt;layer 2 survived whatever killed layer 3&lt;/a&gt;. This is the order verified end-to-end on the reference machine.&lt;/p&gt;
&lt;h2 id="1-inventory-your-backups"&gt;1. Inventory your backups&lt;a class="anchor" href="#1-inventory-your-backups"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Minimum viable: the config set (git repo or any copy) and the MCU state. Already-mainline MCUs need nothing here; vendor MCUs need the firmware steps below. A full eMMC image makes this a restore instead of a rebuild. → &lt;a href="https://sovol.lexfrei.dev/zero/os/recovery/"&gt;Recovery&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Clean-slate (eMMC reader)</title><link>https://sovol.lexfrei.dev/zero/os/clean-slate/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sovol.lexfrei.dev/zero/os/clean-slate/</guid><description>&lt;h1 id="clean-slate-install-with-an-emmc-reader"&gt;Clean-slate install with an eMMC reader&lt;a class="anchor" href="#clean-slate-install-with-an-emmc-reader"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;The cleanest OS path: pull the eMMC module, flash it offline in a USB reader, bake in everything first boot needs, and power up a configured machine. This is the exact sequence used to (re)build the reference machine — twice — so every step has survived contact with reality.&lt;/p&gt;
&lt;p&gt;Prerequisites: the eMMC module in a USB reader, a Linux machine or VM for the offline edits (macOS cannot write ext4 — see the offline-edit note below), and the MCUs already on mainline Katapult + Klipper (see &lt;a href="https://sovol.lexfrei.dev/zero/firmware/mcu-migration/"&gt;MCU migration&lt;/a&gt;). If the MCUs ran mainline before, they still do — &lt;a href="https://sovol.lexfrei.dev/concepts/"&gt;layer 2 survives layer 3&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>MCU migration</title><link>https://sovol.lexfrei.dev/zero/firmware/mcu-migration/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sovol.lexfrei.dev/zero/firmware/mcu-migration/</guid><description>&lt;h1 id="mcu-migration--both-mcus-onto-mainline"&gt;MCU migration — both MCUs onto mainline&lt;a class="anchor" href="#mcu-migration--both-mcus-onto-mainline"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;The clean way to put both MCUs fully on upstream Klipper — app &lt;em&gt;and&lt;/em&gt; bootloader, no vendor bytes in the firmware. Build everything from the &lt;strong&gt;same Klipper &lt;code&gt;master&lt;/code&gt; commit&lt;/strong&gt; (see &lt;a href="https://sovol.lexfrei.dev/concepts/"&gt;why master&lt;/a&gt;). The order is: build all four images, flash the toolhead once over SWD, then the mainboard over USB-Katapult.&lt;/p&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites&lt;a class="anchor" href="#prerequisites"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;An SWD programmer&lt;/strong&gt; — ST-Link V2 (~$3 clone) or a Flipper Zero running the DAP Link app. Needed once, to bootstrap the toolhead: the vendor Katapult is request-only and can&amp;rsquo;t be recovered over CAN, so you flash a CAN-capable mainline Katapult onto the toolhead over SWD the first time, and never open the head again.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ARM toolchain&lt;/strong&gt; — &lt;code&gt;arm-none-eabi-gcc&lt;/code&gt; (already on the printer host) or &lt;code&gt;brew install --cask gcc-arm-embedded&lt;/code&gt; on macOS. See &lt;a href="https://sovol.lexfrei.dev/zero/firmware/build/"&gt;Building the firmware&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;openocd&lt;/code&gt; ≥ 0.11 for the SWD flash.&lt;/li&gt;
&lt;li&gt;SSH access to the printer.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="back-up-first"&gt;Back up first&lt;a class="anchor" href="#back-up-first"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before erasing anything, take your rollback — the SWD dump of the toolhead especially. The full backup checklist (vendor stack, SWD dump, eMMC image) is on &lt;a href="https://sovol.lexfrei.dev/zero/os/recovery/"&gt;the recovery page&lt;/a&gt;. The one that matters most here:&lt;/p&gt;</description></item><item><title>Plugins</title><link>https://sovol.lexfrei.dev/zero/application/plugins/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sovol.lexfrei.dev/zero/application/plugins/</guid><description>&lt;h1 id="plugins-and-venv-extras"&gt;Plugins and venv extras&lt;a class="anchor" href="#plugins-and-venv-extras"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;The add-ons this machine actually runs, on top of the stock KIAUH stack.&lt;/p&gt;
&lt;h2 id="scipy--required-by-the-eddy-probe"&gt;scipy — required by the eddy probe&lt;a class="anchor" href="#scipy--required-by-the-eddy-probe"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Install &lt;code&gt;scipy&lt;/code&gt; into the Klipper venv:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;~/klippy-env/bin/pip install scipy&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Without it the eddy probe calibration fails. If PyPI stalls when downloading from the board, sideload the wheels — see &lt;a href="https://sovol.lexfrei.dev/zero/troubleshooting/"&gt;troubleshooting&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="sovol_codes--the-knob-screen-codes"&gt;sovol_codes — the knob-screen codes&lt;a class="anchor" href="#sovol_codes--the-knob-screen-codes"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The vendor firmware shows numeric codes on the knob screen (&lt;code&gt;101&lt;/code&gt;/&lt;code&gt;103&lt;/code&gt;, the &lt;code&gt;60+&lt;/code&gt; shutdown range); mainline shows human-readable messages. To keep the codes on upstream Klipper, install the opt-in &lt;code&gt;sovol_codes.py&lt;/code&gt; plugin:&lt;/p&gt;</description></item><item><title>Recovery</title><link>https://sovol.lexfrei.dev/zero/runbooks/recovery/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sovol.lexfrei.dev/zero/runbooks/recovery/</guid><description>&lt;h1 id="runbook--recovering-a-machine-that-wont-come-up"&gt;Runbook — recovering a machine that won&amp;rsquo;t come up&lt;a class="anchor" href="#runbook--recovering-a-machine-that-wont-come-up"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Route by what actually failed. Because &lt;a href="https://sovol.lexfrei.dev/concepts/"&gt;layer 2 survives layer 3&lt;/a&gt;, most recoveries are narrower than they feel — a dead OS doesn&amp;rsquo;t touch the MCUs, and a bad app flash doesn&amp;rsquo;t touch the OS.&lt;/p&gt;
&lt;p&gt;The backup checklist and the detailed rollbacks live on &lt;a href="https://sovol.lexfrei.dev/zero/os/recovery/"&gt;the recovery page&lt;/a&gt;; this is the routing.&lt;/p&gt;
&lt;h2 id="the-os-wont-boot"&gt;The OS won&amp;rsquo;t boot&lt;a class="anchor" href="#the-os-wont-boot"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The MCUs are fine. Rebuild only the OS, then reconnect.&lt;/p&gt;</description></item><item><title>Calibration</title><link>https://sovol.lexfrei.dev/zero/application/calibration/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sovol.lexfrei.dev/zero/application/calibration/</guid><description>&lt;h1 id="calibrate-and-verify"&gt;Calibrate and verify&lt;a class="anchor" href="#calibrate-and-verify"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;With both MCUs on mainline, the config translated, and plugins in, calibrate the eddy probe and motion, then prove it with plastic.&lt;/p&gt;
&lt;h2 id="eddy-and-tap"&gt;Eddy and tap&lt;a class="anchor" href="#eddy-and-tap"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Run in order, &lt;code&gt;SAVE_CONFIG&lt;/code&gt; after each:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;LDC_CALIBRATE_DRIVE_CURRENT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PROBE_EDDY_CURRENT_CALIBRATE&lt;/code&gt; — builds the freq→height table&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PROBE_EDDY_CURRENT_TAP_CALIBRATE&lt;/code&gt; — sets &lt;code&gt;tap_threshold&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="belt-tension"&gt;Belt tension&lt;a class="anchor" href="#belt-tension"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Aim for ~110 Hz plucking the XY belts over their 150 mm span. (The Z belt is factory ~137 Hz, but that&amp;rsquo;s a 21.5 cm span — a different length, so don&amp;rsquo;t compare the two numbers.) Tighter than that only cleans up the shaper graphs on paper and adds ringing. Klipper&amp;rsquo;s belt &lt;em&gt;similarity&lt;/em&gt; test is unreliable here — the head-mounted accelerometer is noisy at standstill from motor hold-current buzz, so its readings swing run to run. Check tension by ear or a phone tuner instead (Android works; iPhone noise suppression corrupts the reading).&lt;/p&gt;</description></item><item><title>In place, no eMMC reader</title><link>https://sovol.lexfrei.dev/zero/os/in-place/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sovol.lexfrei.dev/zero/os/in-place/</guid><description>&lt;h1 id="reprovisioning-the-os-without-an-emmc-reader"&gt;Reprovisioning the OS without an eMMC reader&lt;a class="anchor" href="#reprovisioning-the-os-without-an-emmc-reader"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;No reader, and you don&amp;rsquo;t want to pull the module? You can put a fresh OS on the eMMC from the running board. The trick is the microSD slot: the H616 boots SD before eMMC, so you boot a fresh image from a card and clone it onto the eMMC from there.&lt;/p&gt;
&lt;p&gt;There is no shortcut over USB — the board exposes no USB-C / OTG port, so the usual &lt;code&gt;sunxi-fel&lt;/code&gt; + U-Boot &lt;code&gt;ums&lt;/code&gt; route to reach the eMMC over USB is off the table (see &lt;a href="https://sovol.lexfrei.dev/zero/os/armbian/#the-board-the-emmc-and-why-fel-is-off-the-table#the-board-the-emmc-and-why-fel-is-off-the-table"&gt;why FEL is out&lt;/a&gt;). SD-boot-and-clone is the only no-reader path.&lt;/p&gt;</description></item><item><title>Extras</title><link>https://sovol.lexfrei.dev/zero/application/extras/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sovol.lexfrei.dev/zero/application/extras/</guid><description>&lt;h1 id="extras--optional-hardware-and-practices"&gt;Extras — optional hardware and practices&lt;a class="anchor" href="#extras--optional-hardware-and-practices"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Additions that are not part of the core migration but earned their place on a real machine.&lt;/p&gt;
&lt;h2 id="usb-wifi-dongle-when-the-onboard-radio-dies"&gt;USB WiFi dongle (when the onboard radio dies)&lt;a class="anchor" href="#usb-wifi-dongle-when-the-onboard-radio-dies"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The onboard RTL8189FTV is a known single point of failure — on this unit it died of PSU-inflicted causes (&lt;code&gt;mmc: error -110 whilst initialising SDIO card&lt;/code&gt; on every boot, on stock firmware too, through ~21 attempts across two kernel stacks; software revival — power-cycling the chip via its GPIO, longer &lt;code&gt;post-power-on-delay-ms&lt;/code&gt;, lower SDIO clock — changes nothing). If you see that signature, stop debugging and plug a dongle into one of the board&amp;rsquo;s USB-A ports.&lt;/p&gt;</description></item><item><title>Updatable Armbian</title><link>https://sovol.lexfrei.dev/zero/os/updatable/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sovol.lexfrei.dev/zero/os/updatable/</guid><description>&lt;h1 id="keeping-armbian-updatable"&gt;Keeping Armbian updatable&lt;a class="anchor" href="#keeping-armbian-updatable"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;The worry that an &lt;code&gt;apt&lt;/code&gt; upgrade will &amp;ldquo;lose the dts&amp;rdquo; and break the eMMC is mostly unfounded, and the real constraint is narrower than it looks. This page separates the two.&lt;/p&gt;
&lt;blockquote class='book-hint note'&gt;
&lt;p&gt;&lt;strong&gt;Experimental in one place.&lt;/strong&gt; Everything about &lt;em&gt;why&lt;/em&gt; the kernel is held is confirmed and documented. The path &lt;em&gt;off&lt;/em&gt; the hold (moving to a newer kernel and keeping onboard Ethernet) is not yet verified on the Zero — it&amp;rsquo;s flagged below. Take a &lt;a href="https://sovol.lexfrei.dev/zero/os/recovery/#back-up-first-the-checklist#back-up-first-the-checklist"&gt;full backup&lt;/a&gt; before testing it.&lt;/p&gt;</description></item><item><title>Recovery</title><link>https://sovol.lexfrei.dev/zero/os/recovery/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sovol.lexfrei.dev/zero/os/recovery/</guid><description>&lt;h1 id="recovery-and-backups"&gt;Recovery and backups&lt;a class="anchor" href="#recovery-and-backups"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;What makes every step in every path reversible, and how to get back a machine that won&amp;rsquo;t boot. Recovery is mostly a backup story: take the right snapshots before you touch anything, and a dead layer becomes a restore instead of a rebuild.&lt;/p&gt;
&lt;h2 id="back-up-first-the-checklist"&gt;Back up first — the checklist&lt;a class="anchor" href="#back-up-first-the-checklist"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Take these before erasing anything. They are what make each later step reversible.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The vendor stack&lt;/strong&gt; (file-level, resumable rsync — not a raw &lt;code&gt;dd&lt;/code&gt; over WiFi): vendor &lt;code&gt;~/klipper&lt;/code&gt; as a git bundle, &lt;code&gt;~/printer_data/config&lt;/code&gt;, &lt;code&gt;~/printer_data/build/*.bin&lt;/code&gt;, and the per-chip build configs &lt;code&gt;~/klipper/.config*&lt;/code&gt; (useful seeds even though their flash offsets are stale).&lt;/p&gt;</description></item><item><title>Troubleshooting</title><link>https://sovol.lexfrei.dev/zero/troubleshooting/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sovol.lexfrei.dev/zero/troubleshooting/</guid><description>&lt;h1 id="troubleshooting--tuning"&gt;Troubleshooting &amp;amp; tuning&lt;a class="anchor" href="#troubleshooting--tuning"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Things that bite when running a Sovol Zero on mainline Klipper, and how to clear them. Facts and fixes only — the full procedures live in the layer pages.&lt;/p&gt;
&lt;h2 id="flashing--can"&gt;Flashing &amp;amp; CAN&lt;a class="anchor" href="#flashing--can"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="canbus_query--flashtoolpy--q-shows-0-nodes"&gt;canbus_query / flashtool.py -q shows 0 nodes&lt;a class="anchor" href="#canbus_query--flashtoolpy--q-shows-0-nodes"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If Klipper is &lt;strong&gt;stopped&lt;/strong&gt;, a query returning &lt;code&gt;Total 0 uuids&lt;/code&gt; is normal — those tools enumerate only un-initialised / bootloader nodes, and a Klipper-configured app node does not answer. Read it as &amp;ldquo;everything is running its application&amp;rdquo;, not &amp;ldquo;the bus is dead&amp;rdquo;. Start Klipper (or put a node into its bootloader) to see it in a query.&lt;/p&gt;</description></item><item><title>Resources</title><link>https://sovol.lexfrei.dev/zero/resources/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sovol.lexfrei.dev/zero/resources/</guid><description>&lt;h1 id="plugin--patches"&gt;Plugin &amp;amp; patches&lt;a class="anchor" href="#plugin--patches"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Two artifacts live as source in the repository, version-controlled and downloadable, and are documented here. They stay as code — the site describes them, the repo holds them.&lt;/p&gt;
&lt;h2 id="sovol_codes--the-knob-screen-codes-plugin"&gt;&lt;code&gt;sovol_codes&lt;/code&gt; — the knob-screen codes plugin&lt;a class="anchor" href="#sovol_codes--the-knob-screen-codes-plugin"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The vendor Klipper fork shows numeric codes on the knob screen (&lt;code&gt;101&lt;/code&gt;, &lt;code&gt;103&lt;/code&gt;, the &lt;code&gt;60+&lt;/code&gt; shutdown range) by &lt;strong&gt;editing upstream core files in place&lt;/strong&gt; — &lt;code&gt;klippy/extras/homing.py&lt;/code&gt;, &lt;code&gt;klippy/klippy.py&lt;/code&gt;, &lt;code&gt;klippy/kinematics/corexy.py&lt;/code&gt;. That couples product UI to Klipper core and is the reason the printer is stuck on a squashed vendor snapshot instead of tracking upstream.&lt;/p&gt;</description></item></channel></rss>