Krux Installer is a GUI based tool to flash Krux without typing any command in terminal for flash the firmware onto the device.
Available for:
- Linux:
- Debian-like;
- Fedora-like;
- In the experimental phase, we have a nix flake for development.
- Windows;
- MacOS:
- intel processors;
- arm64 processors (M1/M2/M3/M4).
Make sure you have python:
python --versionGenerally, all Linux come with python.
Follow the instructions at python.org
Before installing krux-installer source code, you will need prepare the system:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"brew install pythonand add this line to your ~/.zshrc:
alias python=python3Python's ssl module relies on OpenSSL for cryptographic operations.
Ensure that OpenSSL is installed on your system and is compatible with the
Python version you're using.
Since we expect that you're using the Python installed with Homebrew, it's recommended to install OpenSSL through Homebrew if it's not already installed:
brew install opensslAfter installing OpenSSL, make sure it's linked correctly:
brew link --force opensslThis ensures that the OpenSSL libraries are available in the expected locations that Python can find and use.
Library paths on MacOS involves verifying that the environment variables and system
configurationsare correctyly set to find the necessary libraries, such as OpenSSL,
which is crucial for the ssl module in Python.
On MacOS, the dynamic linker tool dyld uses environment variabes to locate shared
libraries. The primary environment variable for specifying library paths is
DYLD_LIBRARY_PATH.
Adding the lines below to your ~/.zshrc (or similar) the DYLD_LIBRARY_PATH
will be set each time you open a new terminal session (and therefore the OpenSSL
libraries libcrypto.dylib and libssl.dylib will can be found):
OPENSSL_MAJOR_VERSION=`openssl --version | awk '{ print $2}' | cut -d . -f1`
OPENSSL_FULL_VERSION=`openssl --version | awk ' { print $2}'`
export DYLD_LIBRARY_PATH="/opt/homebrew/Cellar/openssl@$OPENSSL_MAJOR_VERSION/$OPENSSL_FULL_VERSION/lib:$DYLD_LIBRARY_PATH"Follow the steps to install UV on [https://docs.astral.sh/uv/reference/storage/]
Clone the repository:
git clone --recurse-submodules https://github.com/selfcustody/krux-installer.gitInstall python dependencies:
uv syncIf already cloned the repo without using --recurse-submodules,
use the command below to clone the needed submodules:
git submodule update --initKrux-Installer uses poe task manager for formatting, linting, tests,
coverage and build.
uv run poeuv run poe formatuv run poe lintuv run poe testFor systems without a window manager:
# Linux only
uv run poe test --no-xvfbYou can see all coverage results opening you browser and type
file:///<folder>/krux-installer/htmlcov/index.html (assuming
folder is where you placed the krux-installer project).
uv sync --extra builder
uv run poe fetch-firmware
uv run poe build-linuxuv sync --extra builder
uv run poe fetch-firmware
uv run poe build-macosuv sync --extra builder
uv run poe fetch-firmware
uv run poe build-winIt will export all project in a
one-file binary:
- linux:
./dist/krux-installer - macOS:
./dist/krux-installer.app/Contents/MacOS/krux-installer - windows:
./dist/krux-installer.exe
To more options see .ci/create-spec.py against the PyInstaller options.
The installer ships with firmware binaries embedded at build time. This section documents how the embedding pipeline works and how to use locally built binaries for development or testing.
prebuild/
└── fetch_firmware.sh # canonical script: download → verify → embed
.firmware_download/ # landing folder (gitignored)
├── krux-<version>.zip
├── krux-<version>.zip.sha256.txt
├── krux-<version>.zip.sig
└── selfcustody.pem
src/utils/firmware/ # packing folder (committed, embedded in the binary)
└── <version>/
├── amigo.kfpkg
├── bit.kfpkg # not present in all releases
├── cube.kfpkg
├── dock.kfpkg
├── embed_fire.kfpkg
├── m5stickv.kfpkg
├── tzt.kfpkg
├── wonder_k.kfpkg
├── wonder_mv.kfpkg
└── yahboom.kfpkg
The .firmware_download/ landing folder holds the raw assets from GitHub
(zip, checksum, signature and public key). It is gitignored and can be
deleted after a successful build.
The src/utils/firmware/<version>/ packing folder contains only the
extracted .kfpkg files — one per supported device. These are committed
to the repository and embedded into the installer binary by PyInstaller
at build time.
uv sync --extra builder
uv run poe fetch-firmwareThis runs prebuild/fetch_firmware.sh, which:
- Downloads the release zip, SHA256 checksum, ECDSA signature and
selfcustody.pemfrom GitHub into.firmware_download/; - Verifies the SHA256 checksum (
sha256sumon Linux,shasumon macOS); - Verifies the ECDSA signature with
openssl(warns and continues ifopensslis not available); - Extracts
kboot.kfpkgfor each supported device and saves it assrc/utils/firmware/<version>/<device>.kfpkg.
Required tools in PATH: curl, unzip.
Optional (for full verification): sha256sum/shasum, openssl.
If you are developing Krux firmware and want to test your locally compiled
binaries with the installer, place your .kfpkg files directly into the
packing folder — no download step needed:
src/utils/firmware/<version>/
├── amigo.kfpkg ← your locally built binary
└── ...
The version directory must match the FIRMWARE_VERSION constant in
src/utils/constants/__init__.py. When running the installer from source
(uv run poe dev), it will pick up whatever .kfpkg files are present
in that folder.
Note: locally built binaries are unsigned. The installer will still flash them correctly; only the pre-build verification step (
fetch_firmware.sh) requires a valid signature. No signature is checked at flash time.
After building the installer, the landing folder is no longer needed:
rm -rf .firmware_download/The packing folder (src/utils/firmware/) should be kept as-is if you
want to commit the firmware files for reproducible builds.
