Kern is an experimental project that explores the capabilities of the ESP32-P4 as a platform to perform air-gapped Bitcoin signatures and cryptography.
Kern supports three Waveshare ESP32-P4 boards:
| Board | Display | Touch | Camera |
|---|---|---|---|
ESP32-P4-WiFi6-Touch-LCD-4B (wave_4b) |
720x720 MIPI DSI | GT911 | OV5647 + DW9714 autofocus |
ESP32-P4-WiFi6-Touch-LCD-3.5 (wave_35) |
320x480 SPI | FT5x06 | OV5647 (no autofocus) |
ESP32-P4-WiFi6-Touch-LCD-5 (wave_5) |
720x1280 MIPI DSI | GT911 | OV5647 (no autofocus) |
ESP32-P4 does not contain radio (WiFi, BLE), but these boards have a radio in a secondary chip (ESP32-C6 mini). Later the project will migrate to use radio-less, simpler and cheaper boards with ESP32-P4 only.
An OV5647 camera module is required for both boards.
Checkout to an early 6.1 version which has bugfixes we need for Kern
cd <your ESP-IDF installation dir>
git checkout 44c77cbf46844cd056c923277ece745173cb270d
git submodule update --recursive
./install.sh esp32p4This project uses git submodules. You have two options:
When cloning the project for the first time, make sure to clone it recursively to include all submodules:
git clone --recursive https://github.com/odudex/Kern.gitIf you've already cloned the repository without the --recursive flag, you can initialize and update the submodules with:
git submodule update --init --recursiveBuild with just (recommended) or idf.py directly. All just commands accept a board parameter — wave_4b (default), wave_35, or wave_5:
just build # Build for wave_4b (default)
just build wave_35 # Build for wave_35
just build wave_5 # Build for wave_5
just flash wave_5 # Flash for wave_5
just monitor # Serial monitor
just clean # Required when switching boardsOr using idf.py directly:
# wave_4b
idf.py -D 'SDKCONFIG_DEFAULTS=sdkconfig.defaults;sdkconfig.defaults.wave_4b' build
# wave_35
idf.py -D 'SDKCONFIG_DEFAULTS=sdkconfig.defaults;sdkconfig.defaults.wave_35' build
# wave_5
idf.py -D 'SDKCONFIG_DEFAULTS=sdkconfig.defaults;sdkconfig.defaults.wave_5' buildNote: Switching between boards requires a clean build (
just clean) because sdkconfig is board-specific.
The simulator renders the full LVGL UI in an SDL2 window, matching each board's resolution:
just sim # Run simulator as wave_4b (720x720)
just sim wave_35 # Run simulator as wave_35 (320x480)
just sim wave_5 # Run simulator as wave_5 (720x1280)
just sim-build wave_35 # Build only
just sim-clean # Remove simulator build artifacts
just sim-reset # Wipe simulator data (factory reset)
just sim-qr IMG # Run with a QR image
just sim-webcam # Run with real webcam (V4L2)Switching simulator boards also requires just sim-clean first. See simulator/README.md for details.
After updating ESP-IDF or switching branches with significant build changes, do a full clean to avoid stale artifacts:
idf.py fullclean
rm sdkconfig
idf.py set-target esp32p4
idf.py buildTo enable camera auto-focus, enable camera focus motor on menuconfig:
CONFIG_CAM_MOTOR_DW9714=y
CONFIG_CAMERA_OV5647_ENABLE_MOTOR_BY_GPIO0=y
Pre-release firmware is provided for testing purposes only. Do not use pre-release builds as a signer for real savings.
| Device | Board | Display |
|---|---|---|
wave_4b |
Waveshare ESP32-P4-WiFi6-Touch-LCD-4B | 720x720 MIPI DSI |
wave_35 |
Waveshare ESP32-P4-WiFi6-Touch-LCD-3.5 | 320x480 SPI |
wave_5 |
Waveshare ESP32-P4-WiFi6-Touch-LCD-5 | 720x1280 MIPI DSI |
- Python 3
- USB cable connected to the board
-
Download the zip for your device from the Releases page (e.g.
kern-wave_4b-v0.0.3.zip). -
Unzip the package:
unzip kern-wave_4b-v0.0.3.zipThe zip contains:
bootloader.bin— bootloaderpartition-table.bin— partition tablefirmware.bin— application firmwarekern-v0.0.3.bin— merged binary (all of the above)
- Create a Python virtual environment and install esptool:
python3 -m venv venv
source venv/bin/activate
pip install esptool- Flash the merged binary (clean install):
esptool --chip esp32p4 --baud 460800 write-flash 0x0 kern-v0.0.3.binNote: Flashing the merged binary from offset
0x0erases the entire flash range it covers, including the NVS partition where PIN and settings are stored. To preserve NVS data when updating, flash the individual binaries instead:esptool --chip esp32p4 --baud 460800 write-flash \ 0x2000 bootloader.bin \ 0x8000 partition-table.bin \ 0x20000 firmware.bin
Kern is strongly inspired by Krux, sharing similar but simplified UI elements and flow.
Blockstream Jade was a strong inspiration for the decision to use C language for efficient use of the hardware. Additionally, Kern uses the same core library Jade does, libwally, is shared with Jade.
The simplicity and UI polish of SeedSigner and the security focus of the pioneering Specter-DIY were also strong inspirations.








