Building for Trezor Model T? See the core documentation.
Ensure that you have Docker installed. You can follow Docker's installation instructions.
Clone this repository, then use
build-docker.sh to build all images:
git clone https://github.com/trezor/trezor-firmware.git cd trezor-firmware ./build-docker.sh
When the build is done, you will find the current firmware in
It is possible to run
build-docker.sh if either your Docker is configured in rootless mode,
or if your user is a member of the
docker group; see Docker documentation
If you don't satisfy the above conditions, and run
sudo ./build-docker.sh, you might receive a
error. To work around it, make sure that the directory hierarchy in
is world-writable - e.g., by running
chmod -R a+w build/.
For firmware versions 1.8.1 and newer, you can checkout the respective tag locally.
To build firmware 1.8.2, for example, run
git checkout legacy/v1.8.2 and then use
the instructions below.
Note that the unified Docker build was added after version 1.8.3, so it is not available for older versions.
For firmwares older than 1.8.1, please clone the archived trezor-mcu repository and follow the instructions in its README.
Make sure you have Python 3.6 or later and Poetry installed.
The build process is configured via environment variables:
EMULATOR=1specifies that an emulator should be built, instead of the device firmware.
DEBUG_LINK=1specifies that DebugLink should be available in the built image.
PRODUCTION=0disables memory protection. This is necessary for installing unofficial firmware.
DEBUG_LOG=1enables debug messages to be printed on device screen.
BITCOIN_ONLY=1specifies Bitcoin-only version of the firmware.
To run the build process, execute the following commands:
# enter the legacy subdirectory cd legacy # set up poetry poetry install # set up environment variables. For example, to build emulator with debuglink: export EMULATOR=1 DEBUG_LINK=1 # clear build artifacts poetry run ./script/setup # run build process poetry run ./script/cibuild
A built device firmware will be located in
legacy/firmware/trezor.bin. A built emulator will be
"Exception: bootloader has to be smaller than 32736 bytes": if you didn't modify the bootloader source code, simply make sure you always run
"error adding symbols: File in wrong format": This happens when building emulator after building the firmware, or vice-versa. Execute the following command to fix the problem:
find -L vendor -name "*.o" -delete
You can launch the emulator using
./firmware/trezor.elf. To use
trezorctl with the emulator, use
trezorctl -p udp (for example,
trezorctl -p udp get_features).
You can use
TREZOR_OLED_SCALE environment variable to make emulator screen bigger.
- Pick version of firmware binary listed on https://data.trezor.io/firmware/1/releases.json
- Download it:
wget -O trezor.signed.bin https://data.trezor.io/firmware/1/trezor-1.9.4.bin
trezorctldry-run mode to get the firmware fingerprint:
trezorctl firmware-update -n -f trezor.signed.bin
Step 3 should produce the same fingerprint like your local build (for the same version tag).
WARNING: This will erase the recovery seed stored on the device! You should never do this on Trezor that contains coins!
PRODUCTION=0 or you will get a hard fault on your device.
Switch your device to bootloader mode, then execute:
trezorctl firmware-update -f build/legacy/firmware/firmware.bin
Not all combinations of bootloader and firmware will work. This depends on 3 variables: PRODUCTION of bootloader, PRODUCTION of firmware, whether firmware is signed
This table shows the result for bootloader 1.8.0+ and 1.9.1+:
|Bootloader PRODUCTION||Firmware PRODUCTION||Is firmware officially signed?||Result|
|1||1||yes||works, official configuration|
|1||1||no||hardfault in header.S when setting VTOR and stack|
|0||1||no||works, but don't forget to comment out |
|0||0||no||hard fault because header.S doesn't set VTOR and stack right|
The other three possibilities with signed firmware and
PRODUCTION!=0 for bootloader/firmware don't exist.
legacy/imhex/ directory in repo and
README.md there how to use it to parse headers from existing images.