Flashing Katapult Bootloader and Klipper Firmware on Creality 4.2.2 Board without a working bootloader
I accidentally broke the bootloader on my Creality 4.2.2 board while flashing Klipper. These instructions show how I recovered and how I flashed Klipper and Katapult as bootloader. You can always follow these steps also if you have a working bootloader and could flash via SD card as with Katapult you can update Klipper without the SD card.
- Hardware Requirements
- Software Requirements
- Wiring Setup
- Setting Up OpenOCD on Raspberry Pi
- Compiling Katapult Bootloader
- Flashing Katapult via OpenOCD
- Compiling Klipper Firmware
- Flashing Klipper via OpenOCD
- Verifying the Installation
- Future Firmware Updates
- Troubleshooting
- Creality 4.2.2 board (STM32F103 MCU)
- Raspberry Pi (any model with GPIO, used as SWD programmer)
- Jumper wires for SWD connection
- USB cable or Serial UART adapter for communication
- Power supply for the 3D printer board
- Raspberry Pi OS (Raspbian)
- OpenOCD (compiled with bcm2835gpio support)
- Git
- Build tools (gcc, make, etc.)
Connect the following pins between your Raspberry Pi and the Creality 4.2.2 board's SWD header:
| Raspberry Pi GPIO | Function | Creality 4.2.2 SWD Header |
|---|---|---|
| GPIO 25 (Pin 22) | SWCLK | SWCLK |
| GPIO 24 (Pin 18) | SWDIO | SWDIO |
| GND (Pin 20) | Ground | GND |
| 3.3V (Pin 1) | Power | 3.3V (optional) |
After flashing, connect the Creality 4.2.2 board to your Raspberry Pi (or host computer) via USB cable. The board will appear as a USB serial device.
sudo apt update
sudo apt install git autoconf libtool make pkg-config libusb-1.0-0-dev telnetOpenOCD must be compiled from source to enable bcm2835gpio support:
cd ~
git clone https://github.com/openocd-org/openocd.git
cd openocd
./bootstrap
./configure --enable-bcm2835gpio --enable-sysfsgpio
make -j$(nproc)
sudo make installCreate a configuration file for the STM32F103 target:
nano ~/stm32-flash.cfgAdd the following content:
source [find interface/raspberrypi-native.cfg]
bcm2835gpio_swd_nums 25 24
transport select swd
source [find target/stm32f1x.cfg]
adapter speed 1000
Explanation:
raspberrypi-native.cfg: Uses Raspberry Pi GPIO as programmerbcm2835gpio_swd_nums 25 24: Sets GPIO 25 as SWCLK and GPIO 24 as SWDIOtransport select swd: Uses Serial Wire Debug protocolstm32f1x.cfg: Target configuration for STM32F1 familyadapter speed 1000: Sets clock speed to 1000 kHz (1 MHz)
Save and exit (Ctrl+X, then Y, then Enter).
Ensure the wiring is correct and the board is powered, then test the connection:
sudo openocd -f ~/stm32-flash.cfgYou should see output similar to:
Open On-Chip Debugger 0.12.0
...
Info : SWD DPIDR 0x1ba01477
Info : [stm32f1x.cpu] Cortex-M3 r1p1 processor detected
Info : [stm32f1x.cpu] target has 6 breakpoints, 4 watchpoints
Info : Listening on port 4444 for telnet connections
If successful, press Ctrl+C to stop OpenOCD. You're ready to proceed!
cd ~
git clone https://github.com/Arksine/katapult
cd katapultRun menuconfig:
make menuconfigConfigure with the following settings:
Micro-controller Architecture: STMicroelectronics STM32
Processor model: STM32F103
[ ] Only 10KiB of RAM (for rare stm32f103x6 variant)
[ ] Disable SWD at startup (for GigaDevice stm32f103 clones)
Build Katapult deployment application: Do not build
Clock Reference: 8 MHz crystal
Communication interface: Serial (on USART1 PA10/PA9)
Application start offset: 8KiB offset
GPIO pins to set on bootloader entry: (leave blank)
[*] Support bootloader entry on rapid double click of reset button
[ ] Enable bootloader entry on button (or gpio) state
[ ] Enable Status LED
Key Points:
- 8 MHz crystal: Standard for Creality 4.2.2
- USB on PA11/PA12: Standard USB interface for communication
- 8KiB offset: Reserves first 8KB for Katapult, application starts after
- Double-click reset: Convenient bootloader entry method
Save and exit.
make clean
makeThe compiled bootloader will be at ~/katapult/out/katapult.bin.
Verify the file exists:
ls -lh ~/katapult/out/katapult.binIn a terminal, start OpenOCD in the background:
sudo openocd -f ~/stm32-flash.cfg &You should see:
Info : Listening on port 4444 for telnet connections
Open a new terminal and connect to OpenOCD:
telnet localhost 4444You'll see:
Connected to localhost.
Open On-Chip Debugger
>
In the telnet session, execute the following commands one at a time:
reset halt
stm32f1x unlock 0
reset halt
flash write_image erase /home/YOUR_USERNAME/katapult/out/katapult.bin 0x08000000
verify_image /home/YOUR_USERNAME/katapult/out/katapult.bin 0x08000000
reset
exitReplace YOUR_USERNAME with your actual username (e.g., /home/pi/katapult/out/katapult.bin).
Expected Output:
[stm32f1x.cpu] halted due to debug-request
device id = 0x10036414
flash size = 512 KiB
stm32x unlocked.
wrote 3048 bytes from file ... in 0.217286s
verified 3048 bytes in 0.058051s
After running reset, you may see a hard fault error. This is normal because Katapult expects a valid application (Klipper) at the 8KiB offset, which we'll flash next.
cd ~/klipperIf Klipper isn't installed:
cd ~
git clone https://github.com/Klipper3d/klipper
cd klipperRun menuconfig:
make menuconfigConfigure with the following settings (must match Katapult):
Micro-controller Architecture: STMicroelectronics STM32
Processor model: STM32F103
Bootloader offset: 8KiB bootloader
Clock Reference: 8 MHz crystal
Communication interface: Serial (on USART1 PA10/PA9)
CRITICAL:
- Bootloader offset MUST be 8KiB to match Katapult
- Communication interface MUST match Katapult (Serial (on USART1 PA10/PA9))
Save and exit.
make clean
makeThe compiled firmware will be at ~/klipper/out/klipper.bin.
Verify:
ls -lh ~/klipper/out/klipper.bintelnet localhost 4444In the telnet session, execute:
reset halt
flash write_image erase /home/YOUR_USERNAME/klipper/out/klipper.bin 0x08002000
verify_image /home/YOUR_USERNAME/klipper/out/klipper.bin 0x08002000
reset
exitImportant: Note the address 0x08002000 (not 0x08000000). This is the 8KiB offset where the application starts.
Expected Output:
wrote 37256 bytes from file ... in 1.637276s
verified 37256 bytes in 0.539372s
After successfully flashing both Katapult and Klipper, you can stop OpenOCD:
sudo pkill openocdDisconnect the SWD wires between the Raspberry Pi and Creality board. The programmer is no longer needed for future updates.
Connect a USB cable between the Creality 4.2.2 board and your Raspberry Pi (or host computer).
Verify Katapult is working by requesting the bootloader:
~/katapult/scripts/flashtool.py -r -d /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0Expected Output:
Connecting to Serial Device...
Requesting serial bootloader...
Bootloader Request Complete
After Klipper boots, find the USB device:
ls /dev/serial/by-id/You should see something like:
usb-Klipper_stm32f103xe_XXXXXXXXXXXXXXXX-if00
Add the MCU configuration to your printer.cfg:
[mcu]
serial: /dev/serial/by-id/usb-Klipper_stm32f103xe_XXXXXXXXXXXXXXXX-if00sudo systemctl restart klippersudo systemctl status klipperOr check your web interface (Mainsail/Fluidd) - the MCU should show as connected.
Now that Katapult is installed, you can update Klipper firmware without needing OpenOCD or the SWD programmer.
# Step 1: Compile new Klipper firmware
cd ~/klipper
make menuconfig # if configuration changes needed
make
# Step 2: Request bootloader entry
~/katapult/scripts/flashtool.py -r -d /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0
# Step 3: Flash the new firmware immediately
~/katapult/scripts/flashtool.py -f ~/klipper/out/klipper.bin -d /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0Note: Replace the device ID with your actual Klipper device ID from /dev/serial/by-id/.
Symptoms:
Error: SWD DPIDR 0x00000000
Error: Failed to connect to target
Solutions:
- Check wiring connections (SWDIO, SWCLK, GND)
- Ensure the board is powered
- Try slower adapter speed: Change
adapter speed 1000toadapter speed 500instm32-flash.cfg - Verify GPIO pins are correct for your Raspberry Pi model
- Check that OpenOCD was compiled with
--enable-bcm2835gpio
Symptoms:
[stm32f1x.cpu] clearing lockup after double fault
xPSR: 0x60000003 pc: 0x2000018c
Cause: This is normal if only Katapult is flashed without Klipper. Katapult expects a valid application.
Solution: Flash Klipper immediately (see Flashing Klipper via OpenOCD).
Symptoms:
Timeout waiting for bootloader response
Solutions:
- Double-click the reset button quickly to enter bootloader mode
- Check USB cable is properly connected and supports data transfer
- Verify the correct device path in
/dev/serial/by-id/ - Use
-rflag to request bootloader:flashtool.py -r -d /dev/serial/by-id/... - Power cycle the board and Raspberry Pi
Symptoms:
Klipper won't start, or immediate crash after boot
Cause: Klipper compiled with wrong bootloader offset.
Solution: Recompile Klipper with 8KiB bootloader offset in menuconfig, then reflash.
Symptoms:
Error writing to flash
Solutions:
- Run
stm32f1x unlock 0before flashing - Ensure flash isn't write-protected
- Try erasing:
flash erase_sector 0 0 lastthen retry - Check if enough space (Katapult ~3KB + Klipper ~35KB)
Symptoms:
- Klipper service shows MCU connection errors
lsusbdoesn't show the Klipper device- Serial device disappears from
/dev/serial/by-id/
Solution: Restart the Raspberry Pi and power cycle the printer board:
# Shut down the Pi
sudo shutdown now
# After Pi shut down, also pull power from the printer board completely
# Wait 5-10 seconds, then power it back onThis clears any stuck USB or serial states that can prevent proper enumeration.
Symptoms:
Permission denied: /dev/serial/by-id/usb-...
Solutions:
# Add user to dialout group
sudo usermod -a -G dialout $USER
# Then logout and login again, or reboot
sudo rebootSymptoms:
Error: couldn't bind telnet to socket on port 4444
Solution:
# Kill existing OpenOCD instance
sudo pkill openocd
# Wait a moment, then restart
sudo openocd -f ~/stm32-flash.cfg| Address Range | Size | Contents |
|---|---|---|
| 0x08000000 - 0x08001FFF | 8 KB | Katapult Bootloader |
| 0x08002000 - 0x0807FFFF | 504 KB | Klipper Firmware |
reset halt # Stop CPU execution
reset # Reset and run
flash info 0 # Show flash information
flash list # List flash banks
mdw 0x08000000 16 # Read memory (16 words from 0x08000000)
exit # Close telnet connection# Show help
~/katapult/scripts/flashtool.py -h
# Request bootloader
~/katapult/scripts/flashtool.py -r -d /dev/serial/by-id/usb-Klipper_stm32f103xe_XXX-if00
# Flash firmware
~/katapult/scripts/flashtool.py -f ~/klipper/out/klipper.bin -d /dev/serial/by-id/usb-Klipper_stm32f103xe_XXX-if00
# Query device info
~/katapult/scripts/flashtool.py -i -d /dev/serial/by-id/usb-Klipper_stm32f103xe_XXX-if00- Katapult by Arksine
- Klipper by Kevin O'Connor
- OpenOCD by the OpenOCD project
This guide is provided as-is for educational purposes. Please refer to individual project licenses for Katapult, Klipper, and OpenOCD.
Last Updated: February 2026
