build(core): make Makefile and CI use xtask
What changed, and why it matters
This commit is a build-system refactor: it switches the Trezor Core firmware build from direct scons/Make invocations to a new wrapper tool called xtask. It also renames output directories and artifact filenames. There is no change to the actual firmware code, cryptographic logic, or device behavior, so it does not introduce or fix a security vulnerability on its own.
No security action required. Treat as ordinary build-system maintenance; verify CI still produces the expected signed artifacts and reproducible builds.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The diff replaces the legacy core/Makefile logic with thin xtask wrappers and preserves the old behavior in a new core/Makefile.scons. CI workflows are updated to use xtask artifact paths (core/build-xtask/artifacts/latest/*) and renamed binaries (firmware-emu, bootloader-emu). A few CI steps are removed or commented out (sizecheck, rust-type-sizes log, QUIET_MODE), and PYOPT=0 is added to one test job. These are build/test infrastructure changes, not runtime security changes.
Changed components
core/Makefilecore/Makefile.scons.github/workflows/core.yml.github/workflows/core-hw.yml.github/actions/build-core-emu/action.ymlroot Makefile ruststyle targetsInspect captured patch +745 / −400
diff --git a/.github/actions/build-core-emu/action.yml b/.github/actions/build-core-emu/action.yml
index ea87b5f6..34585f50 100644
--- a/.github/actions/build-core-emu/action.yml
+++ b/.github/actions/build-core-emu/action.yml
@@ -36,12 +36,8 @@ runs:
- id: prepare_binary
run: |
- TARGET="core/build/unix/trezor-emu-core-${{ inputs.model }}-v${{ inputs.version }}${{ inputs.binary-suffix }}"
- if [ "${{ inputs.binary-suffix }}" = "-arm" ]; then
- mv core/build/unix/trezor-emu-core "$TARGET"
- else
- cp core/build/unix/trezor-emu-core "$TARGET"
- fi
+ TARGET="core/build-xtask/artifacts/latest/trezor-emu-core-${{ inputs.model }}-v${{ inputs.version }}${{ inputs.binary-suffix }}"
+ mv core/build-xtask/artifacts/latest/firmware-emu "$TARGET"
echo "binary_path=$TARGET" >> "$GITHUB_OUTPUT"
shell: sh
@@ -67,6 +63,6 @@ runs:
with:
name: ${{ inputs.artifact-name }}
path: |
- core/build/unix/trezor-emu-core*
- core/build/bootloader_emu/bootloader.elf
+ core/build-xtask/artifacts/latest/trezor-emu-core*
+ core/build-xtask/artifacts/latest/bootloader-emu
retention-days: 7
diff --git a/.github/workflows/core-hw.yml b/.github/workflows/core-hw.yml
index 873a2d2a..3aef0a8a 100644
--- a/.github/workflows/core-hw.yml
+++ b/.github/workflows/core-hw.yml
@@ -47,7 +47,6 @@ jobs:
--durations=50
--session-timeout 19800
TT_UHUB_PORT: 1
- QUIET_MODE: 1
timeout-minutes: 360 # 6h CI job timeout
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # actions/checkout@v4.3.1
@@ -56,7 +55,7 @@ jobs:
- uses: ./.github/actions/environment
- run: nix-shell --arg hardwareTest true --run uhubctl
- run: nix-shell --run "uv run make -C core build_firmware"
- - run: nix-shell --arg hardwareTest true --run "uv run python ci/hardware_tests/bootstrap.py ${{ matrix.model }} core/build/firmware/firmware.bin"
+ - run: nix-shell --arg hardwareTest true --run "uv run python ci/hardware_tests/bootstrap.py ${{ matrix.model }} core/build-xtask/artifacts/latest/firmware.bin"
- run: nix-shell --run "uv run trezorctl list"
- run: nix-shell --run "uv run trezorctl get-features"
- run: |
@@ -91,7 +90,6 @@ jobs:
DISABLE_OPTIGA: 1
BOOTLOADER_DEVEL: ${{ matrix.model == 'T2B1' && '1' || '0' }}
TT_UHUB_PORT: 1
- QUIET_MODE: 1
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # actions/checkout@v4.3.1
with:
@@ -101,7 +99,7 @@ jobs:
full-deps: "true"
- run: nix-shell --arg hardwareTest true --run uhubctl
- run: nix-shell --run "uv run make -C core build_firmware"
- - run: nix-shell --arg hardwareTest true --run "uv run python ci/hardware_tests/bootstrap.py ${{ matrix.model }} core/build/firmware/firmware.bin"
+ - run: nix-shell --arg hardwareTest true --run "uv run python ci/hardware_tests/bootstrap.py ${{ matrix.model }} core/build-xtask/artifacts/latest/firmware.bin"
- run: nix-shell --run "uv run trezorctl list"
- run: nix-shell --run "uv run trezorctl get-features"
- run: |
diff --git a/.github/workflows/core.yml b/.github/workflows/core.yml
index 5ff9f9dc..bbf4b22e 100644
--- a/.github/workflows/core.yml
+++ b/.github/workflows/core.yml
@@ -77,7 +77,6 @@ jobs:
N4W1: ${{ matrix.n4w1 && '1' || '0' }}
PRODUCTION: ${{ matrix.type == 'production' && '1' || '0' }}
BOOTLOADER_DEVEL: ${{ matrix.model == 'T3W1' && '1' || '0' }}
- QUIET_MODE: 1
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # actions/checkout@v6.0.2
with:
@@ -95,23 +94,16 @@ jobs:
if: matrix.coins == 'universal' && matrix.type != 'debuglink' && matrix.model == 'T3W1'
- run: nix-shell --run "uv run make -C core build_firmware"
- run: nix-shell --run "uv run ./tools/print-rust-stack-sizes.py | sort -k1 -n | tail -n 50"
- - run: nix-shell --run "uv run ./tools/print-rust-type-sizes.sh core/build/firmware/rust-type-sizes.log" | awk '$1 >= 1000' | sort -k1 -n
- - run: nix-shell --run "uv run make -C core sizecheck"
- if: matrix.coins == 'universal' && matrix.type != 'debuglink'
- - run: nix-shell --run "uv run ./tools/check-bitcoin-only core/build/firmware/firmware.bin"
+ # - run: nix-shell --run "uv run ./tools/print-rust-type-sizes.sh core/build/firmware/rust-type-sizes.log" | awk '$1 >= 1000' | sort -k1 -n
+ - run: nix-shell --run "uv run ./tools/check-bitcoin-only core/build-xtask/artifacts/latest/firmware.bin"
if: matrix.coins == 'btconly' && matrix.type != 'debuglink'
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # actions/upload-artifact@v7.0.0
with:
name: core-firmware-${{ matrix.model }}-${{ matrix.coins }}-${{ matrix.type }}${{ matrix.n4w1 && '-n4w1' || '' }}
path: |
- core/build/boardloader/*.bin
- core/build/bootloader/*.bin
- core/build/bootloader_ci/*.bin
- core/build/prodtest/*.bin
- core/build/prodtest_emu/*.bin
- core/build/firmware/firmware.elf
- core/build/firmware/firmware-*.bin
- core/build/firmware/rust-type-sizes.log
+ core/build-xtask/artifacts/latest/*.bin
+ core/build-xtask/artifacts/latest/*.elf
+ core/build-xtask/artifacts/pub/*
retention-days: 7
core_emu:
@@ -143,7 +135,6 @@ jobs:
N4W1: ${{ matrix.n4w1 && '1' || '0' }}
ADDRESS_SANITIZER: ${{ matrix.asan == 'asan' && '1' || '0' }}
LSAN_OPTIONS: "suppressions=../../asan_suppressions.txt"
- QUIET_MODE: 1
DISABLE_TROPIC: 0
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # actions/checkout@v6.0.2
@@ -157,14 +148,14 @@ jobs:
if: ${{ matrix.model == 'T3W1' }}
run: nix-shell --run "uv run model_server tcp -c tests/tropic_model/config.yml > tests/trezor-tropic-model.log 2>&1 &"
- run: nix-shell --run "uv run make -C core test_emu_sanity"
- - run: cp core/build/unix/trezor-emu-core core/build/unix/trezor-emu-core-${{ matrix.model }}-${{ matrix.coins }}${{ matrix.n4w1 && '-n4w1' || '' }}
+ - run: cp core/build-xtask/artifacts/latest/firmware-emu core/build-xtask/artifacts/latest/firmware-emu-${{ matrix.model }}-${{ matrix.coins }}${{ matrix.n4w1 && '-n4w1' || '' }}
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # actions/upload-artifact@v7.0.0
with:
name: core-emu-${{ matrix.model }}-${{ matrix.coins }}-${{ matrix.type }}-${{ matrix.asan }}${{ matrix.n4w1 && '-n4w1' || '' }}
path: |
- core/build/unix/trezor-emu-core*
- core/build/bootloader_emu/bootloader.elf
- core/build/unix/src/**/*.i
+ core/build-xtask/artifacts/latest/firmware-emu*
+ core/build-xtask/artifacts/latest/bootloader-emu
+ core/build-xtask/artifacts/latest/mpy-files/**/*.i
retention-days: 7
core_emu_arm:
@@ -193,7 +184,6 @@ jobs:
N4W1: ${{ matrix.n4w1 && '1' || '0' }}
ADDRESS_SANITIZER: ${{ matrix.asan == 'asan' && '1' || '0' }}
LSAN_OPTIONS: "suppressions=../../asan_suppressions.txt"
- QUIET_MODE: 1
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # actions/checkout@v6.0.2
with:
@@ -202,13 +192,13 @@ jobs:
- run: nix-shell --run "uv run make -C core build_bootloader_emu"
if: matrix.coins == 'universal'
- run: nix-shell --run "uv run make -C core build_unix_frozen"
- - run: mv core/build/unix/trezor-emu-core core/build/unix/trezor-emu-arm-core-${{ matrix.model }}-${{ matrix.coins }}${{ matrix.n4w1 && '-n4w1' || '' }}
+ - run: mv core/build-xtask/artifacts/latest/firmware-emu core/build-xtask/artifacts/latest/firmware-emu-arm-${{ matrix.model }}-${{ matrix.coins }}${{ matrix.n4w1 && '-n4w1' || '' }}
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # actions/upload-artifact@v7.0.0
with:
name: core-emu-arm-${{ matrix.model }}-${{ matrix.coins }}-${{ matrix.type }}-${{ matrix.asan }}${{ matrix.n4w1 && '-n4w1' || '' }}
path: |
- core/build/unix/trezor-emu-*
- core/build/bootloader_emu/bootloader.elf
+ core/build-xtask/artifacts/latest/firmware-emu*
+ core/build-xtask/artifacts/latest/bootloader-emu
retention-days: 2
core_unit_python_test:
@@ -227,6 +217,7 @@ jobs:
ADDRESS_SANITIZER: ${{ matrix.asan == 'asan' && '1' || '0' }}
LSAN_OPTIONS: "suppressions=../../asan_suppressions.txt"
DISABLE_TROPIC: 0
+ PYOPT: 0
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # actions/checkout@v6.0.2
with:
@@ -261,14 +252,14 @@ jobs:
with:
submodules: recursive
- uses: ./.github/actions/environment
- - run: nix-shell --run "uv run make -C core build_unix"
+ - run: nix-shell --run "uv run make -C core -f Makefile.scons build_unix"
# Ensure that "cargo build" works when NOT executed through our makefiles,
# indicating that it does not rely on particular envvars or other flags.
# This makes sure that rust-analyzer will work on our codebase.
- run: nix-shell --run "cd core/embed/rust && cargo build"
if: matrix.asan == 'noasan'
+ - run: nix-shell --run "uv run make -C core -f Makefile.scons test_rust"
- run: nix-shell --run "uv run make -C core clippy"
- - run: nix-shell --run "uv run make -C core test_rust"
- run: nix-shell --run "uv run make -C core audit_rust"
core_rust_client_test:
@@ -286,8 +277,8 @@ jobs:
- uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # actions/download-artifact@v8.0.0
with:
name: core-emu-${{ matrix.model }}-universal-debuglink-noasan
- path: core/build
- - run: chmod +x core/build/unix/trezor-emu-core*
+ path: core/build-xtask/artifacts/latest
+ - run: chmod +x core/build-xtask/artifacts/latest/firmware-emu*
- uses: ./.github/actions/environment
- run: nix-shell --run "uv run core/emu.py --headless -q --temporary-profile --slip0014 --command cargo test --manifest-path rust/trezor-client/Cargo.toml"
@@ -331,8 +322,8 @@ jobs:
- uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # actions/download-artifact@v8.0.0
with:
name: core-emu-${{ matrix.model }}-${{ matrix.coins }}-debuglink-${{ matrix.asan }}${{ matrix.n4w1 && '-n4w1' || '' }}
- path: core/build
- - run: chmod +x core/build/unix/trezor-emu-core*
+ path: core/build-xtask/artifacts/latest
+ - run: chmod +x core/build-xtask/artifacts/latest/firmware-emu*
- uses: ./.github/actions/environment
- name: Start Tropic model
if: ${{ env.TREZOR_MODEL == 'T3W1' && env.ACTIONS_DO_UI_TEST != 'true' }} # ACTIONS_DO_UI_TEST refers to the test_emu_ui_multicore below which uses --control-emulators and starts tvl internally
@@ -389,8 +380,8 @@ jobs:
- uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # actions/download-artifact@v8.0.0
with:
name: core-emu-${{ matrix.model }}-universal-debuglink-${{ matrix.asan }}
- path: core/build
- - run: chmod +x core/build/unix/trezor-emu-core*
+ path: core/build-xtask/artifacts/latest
+ - run: chmod +x core/build-xtask/artifacts/latest/firmware-emu*
- uses: ./.github/actions/environment
- run: nix-shell --run "uv run make -C core test_emu_click_ui_multicore"
if: ${{ matrix.asan == 'noasan' }}
@@ -439,8 +430,8 @@ jobs:
- uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # actions/download-artifact@v8.0.0
with:
name: core-emu-${{ matrix.model }}-universal-debuglink-${{ matrix.asan }}
- path: core/build
- - run: chmod +x core/build/unix/trezor-emu-core*
+ path: core/build-xtask/artifacts/latest
+ - run: chmod +x core/build-xtask/artifacts/latest/firmware-emu*
- uses: ./.github/actions/environment
with:
full-deps: "true"
@@ -480,8 +471,8 @@ jobs:
- uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # actions/download-artifact@v8.0.0
with:
name: core-emu-${{ matrix.model }}-universal-debuglink-${{ matrix.asan }}
- path: core/build
- - run: chmod +x core/build/unix/trezor-emu-core*
+ path: core/build-xtask/artifacts/latest
+ - run: chmod +x core/build-xtask/artifacts/latest/firmware-emu*
- uses: ./.github/actions/environment
- name: Start Tropic model
if: ${{ matrix.model == 'T3W1' }}
@@ -523,13 +514,13 @@ jobs:
- uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # actions/download-artifact@v8.0.0
with:
name: core-emu-${{ matrix.model }}-universal-debuglink-noasan
- path: core/build
- - run: chmod +x core/build/unix/trezor-emu-core*
+ path: core/build-xtask/artifacts/latest
+ - run: chmod +x core/build-xtask/artifacts/latest/firmware-emu*
- uses: ./.github/actions/environment
with:
full-deps: "true"
- run: nix-shell --run "git clone --depth=1 https://github.com/bitcoin-core/HWI.git"
- - run: nix-shell --arg fullDeps true --run "cd HWI && poetry install && poetry run ./test/test_trezor.py --model_t ../core/build/unix/trezor-emu-core bitcoind"
+ - run: nix-shell --arg fullDeps true --run "cd HWI && poetry install && poetry run ./test/test_trezor.py --model_t ../core/build-xtask/artifacts/latest/firmware-emu bitcoind"
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # actions/upload-artifact@v7.0.0
with:
name: core-test-hwi-${{ matrix.model }}
@@ -582,9 +573,9 @@ jobs:
- uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # actions/download-artifact@v8.0.0
with:
name: core-firmware-${{ matrix.model }}-universal-normal # FIXME: s/normal/debuglink/
- path: core/build
+ path: core/build-xtask/artifacts
- uses: ./.github/actions/environment
- - run: nix-shell --run "uv run core/tools/size/checker.py core/build/firmware/firmware.elf"
+ - run: nix-shell --run "uv run core/tools/size/checker.py core/build-xtask/artifacts/latest/firmware.elf"
# Monero tests.
core_monero_test:
@@ -608,8 +599,8 @@ jobs:
- uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # actions/download-artifact@v8.0.0
with:
name: core-emu-${{ matrix.model }}-universal-debuglink-${{ matrix.asan }}
- path: core/build
- - run: chmod +x core/build/unix/trezor-emu-core*
+ path: core/build-xtask/artifacts/latest
+ - run: chmod +x core/build-xtask/artifacts/latest/firmware-emu*
- uses: ./.github/actions/environment
with:
full-deps: "true"
@@ -627,7 +618,7 @@ jobs:
# Tests for U2F and HID.
core_u2f_test:
- name: U2F test (${{ matrix.model }}, ${{ matrix.asan }}
+ name: U2F test (${{ matrix.model }}, ${{ matrix.asan }})
runs-on: ubuntu-latest
needs:
- param
@@ -647,8 +638,8 @@ jobs:
- uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # actions/download-artifact@v8.0.0
with:
name: core-emu-${{ matrix.model }}-universal-debuglink-${{ matrix.asan }}
- path: core/build
- - run: chmod +x core/build/unix/trezor-emu-core*
+ path: core/build-xtask/artifacts/latest
+ - run: chmod +x core/build-xtask/artifacts/latest/firmware-emu*
- uses: ./.github/actions/environment
- name: Start Tropic model
if: ${{ matrix.model == 'T3W1' }}
@@ -665,7 +656,7 @@ jobs:
# FIDO2 device tests.
core_fido2_test:
- name: FIDO2 test (${{ matrix.model }}, ${{ matrix.asan }}
+ name: FIDO2 test (${{ matrix.model }}, ${{ matrix.asan }})
runs-on: ubuntu-latest
needs:
- param
@@ -685,8 +676,8 @@ jobs:
- uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # actions/download-artifact@v8.0.0
with:
name: core-emu-${{ matrix.model }}-universal-debuglink-${{ matrix.asan }}
- path: core/build
- - run: chmod +x core/build/unix/trezor-emu-core*
+ path: core/build-xtask/artifacts/latest
+ - run: chmod +x core/build-xtask/artifacts/latest/firmware-emu*
- uses: ./.github/actions/environment
- name: Start Tropic model
if: ${{ matrix.model == 'T3W1' }}
@@ -733,7 +724,7 @@ jobs:
- uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # actions/download-artifact@v8.0.0
with:
name: core-emu-${{ matrix.model }}-universal-debuglink-noasan
- path: core/build
+ path: core/build-xtask/artifacts/latest
- uses: ./.github/actions/environment
# `make coverage` uses .i files downloaded above
- run: nix-shell --run "uv run make -C core coverage"
@@ -808,15 +799,21 @@ jobs:
with:
pattern: core-emu*debuglink-noasan*
merge-multiple: true
+ path: emulators
- name: Configure aws credentials
uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # aws-actions/configure-aws-credentials@v6.0.0
with:
role-to-assume: arn:aws:iam::538326561891:role/gh_actions_deploy_dev_firmware_data
aws-region: eu-west-1
continue-on-error: true
- - run: |
- rm unix/trezor-emu-core
- aws s3 sync --only-show-errors unix s3://data.trezor.io/dev/firmware/emu-nightly
+ - name: Upload nightly artifacts
+ run: |
+ rm -rf emulators/{bootloader,firmware}-emu emulators/mpy-files emulators/*.json
+ pushd emulators
+ for F in firmware-emu-*; do NEWF=`echo $F | sed s/firmware-emu/trezor-emu-core/`; mv $F $NEWF; done
+ popd
+ tree
+ aws s3 sync --only-show-errors emulators s3://data.trezor.io/dev/firmware/emu-nightly
core_upload_emu_branch:
name: Upload emulator binaries for the current branch
@@ -831,6 +828,7 @@ jobs:
with:
pattern: core-emu*debuglink-noasan*
merge-multiple: true
+ path: emulators
- name: Configure aws credentials
uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # aws-actions/configure-aws-credentials@v6.0.0
with:
@@ -847,8 +845,12 @@ jobs:
echo "branch_name=$branch_name" >> $GITHUB_ENV
- name: Upload artifacts to branch directory
run: |
- rm unix/trezor-emu-core
- aws s3 sync --only-show-errors unix s3://data.trezor.io/dev/firmware/emu-branches/$branch_name
+ rm -rf emulators/{bootloader,firmware}-emu emulators/mpy-files emulators/*.json
+ pushd emulators
+ for F in firmware-emu-*; do NEWF=`echo $F | sed s/firmware-emu/trezor-emu-core/`; mv $F $NEWF; done
+ popd
+ tree
+ aws s3 sync --only-show-errors emulators s3://data.trezor.io/dev/firmware/emu-branches/$branch_name
# Connect
# TODO: core_connect_test
diff --git a/Makefile b/Makefile
index 8fb58f22..aa94e2b6 100644
--- a/Makefile
+++ b/Makefile
@@ -8,6 +8,7 @@ help: ## show this help
PY_FILES = $(shell find . -type f -name '*.py' | sed 'sO^\./OO' | grep -f ./tools/style.py.include | grep -v -f ./tools/style.py.exclude ) common/protob/pb2py
C_FILES = $(shell find . -type f -name '*.[ch]' | grep -f ./tools/style.c.include | grep -v -f ./tools/style.c.exclude )
PROTO_FILES = $(shell find common core -type f -name '*.proto')
+RUST_CRATES = $(shell find core -type f -name Cargo.toml -printf "%h\n")
# suppress black's warning - remove when using Python 3.14
BLACK_FAST ?= 1
@@ -113,15 +114,14 @@ defs_check: ## check validity of coin definitions and protobuf files
python3 common/protob/check.py
python3 common/protob/graph.py common/protob/*.proto
-ruststyle:
+ruststyle: ## apply code style on rust sources
@echo [RUSTFMT]
- @cd core/embed/rust ; cargo fmt
+ @cd core/embed ; cargo fmt
make -C rust style
-ruststyle_check:
- rustfmt --version
+ruststyle_check: ## run code style check on rust sources
@echo [RUSTFMT]
- @cd core/embed/rust ; cargo fmt -- --check
+ @cd core/embed ; cargo fmt -- --check
make -C rust style_check
diff --git a/core/Makefile b/core/Makefile
index 22dcdbeb..c629e7af 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -1,56 +1,11 @@
.PHONY: vendor
-# get the number of CPU cores in a "portable" manner
-# (accounting for darwin and big.LITTLE archs)
-JOBS = $(shell sysctl -n hw.perflevel0.physicalcpu 2>/dev/null ||\
- sysctl -n hw.physicalcpu 2>/dev/null ||\
- sysctl -n hw.ncpu 2>/dev/null ||\
- nproc 2>/dev/null ||\
- echo 4)
-MAKE = make -j $(JOBS)
-
-BUILD_DIR = build
-BOARDLOADER_BUILD_DIR = $(BUILD_DIR)/boardloader
-BOOTLOADER_BUILD_DIR = $(BUILD_DIR)/bootloader
-BOOTLOADER_CI_BUILD_DIR = $(BUILD_DIR)/bootloader_ci
-BOOTLOADER_EMU_BUILD_DIR = $(BUILD_DIR)/bootloader_emu
-PRODTEST_BUILD_DIR = $(BUILD_DIR)/prodtest
-PRODTEST_EMU_BUILD_DIR = $(BUILD_DIR)/prodtest_emu
-KERNEL_BUILD_DIR = $(BUILD_DIR)/kernel
-SECMON_BUILD_DIR = $(BUILD_DIR)/secmon
-FIRMWARE_BUILD_DIR = $(BUILD_DIR)/firmware
-UNIX_BUILD_DIR = $(BUILD_DIR)/unix
-RUST_BUILD_DIR = $(BUILD_DIR)/rust
-
-UNAME_S := $(shell uname -s)
-UNIX_PORT_OPTS ?=
-CROSS_PORT_OPTS ?=
-
-PRODUCTION ?= 0
-DEBUGLINK ?= 0
-PYOPT ?= 1
-BITCOIN_ONLY ?= 0
-FORCE_BOOTLOADER_UPGRADE ?= 0
-BOOTLOADER_DEVEL ?= 0
-UNSAFE_FW ?= 0
+BUILD_DIR = build-xtask/artifacts/latest
+
TREZOR_MODEL ?= T3W1
-TREZOR_MEMPERF ?= 0
-ADDRESS_SANITIZER ?= 0
-CMAKELISTS ?= 0
PYTEST_TIMEOUT ?= 500
TEST_LANG ?= "en"
-THP ?= $(if $(filter T3W1,$(TREZOR_MODEL)),1,0)
-BENCHMARK ?= 0
-LOG_STACK_USAGE ?= 0
-TREZOR_EMULATOR_DEBUGGABLE ?= 0
-QUIET_MODE ?= 0
-TREZOR_DISABLE_ANIMATION ?= $(if $(filter 0,$(PYOPT)),1,0)
-STORAGE_INSECURE_TESTING_MODE ?= 0
-UI_PERFORMANCE_OVERLAY ?= 0
-DBG_CONSOLE ?=
-EXTAPP_SUPPORT ?= 0
-N4W1 ?= 0
ifeq ($(PRODUCTION),1)
ifeq ($(BOOTLOADER_DEVEL),1)
@@ -59,64 +14,6 @@ $(error PRODUCTION and BOOTLOADER_DEVEL cannot be set at the same time)
endif
endif
-# If set, VCP writes will be blocking, in order to allow reliable debug data transmission over VCP.
-# Disabled by default, to prevent debug firmware from getting stuck while writing log messages (if the host is not reading them).
-BLOCK_ON_VCP ?= 0
-
-# OpenOCD interface default. Alternative: ftdi/olimex-arm-usb-tiny-h
-OPENOCD_INTERFACE ?= stlink
-# OpenOCD transport default. Alternative: jtag
-OPENOCD_TRANSPORT ?= hla_swd
-
-# Include the device-specific definitions.
-include embed/models/$(TREZOR_MODEL)/config.mk
-
-# Get bindgen macros for rust tests
-TEST_BINDGEN_MACROS := $(shell tr -d '\n' < embed/models/$(TREZOR_MODEL)/test_bindgen_macros.txt)
-export TEST_BINDGEN_MACROS
-
-
-FLASH_START = $(shell layout_parser ${TREZOR_MODEL} FLASH_START)
-BOARDLOADER_START = $(shell layout_parser ${TREZOR_MODEL} BOARDLOADER_START)
-BOOTLOADER_START = $(shell layout_parser ${TREZOR_MODEL} BOOTLOADER_START)
-KERNEL_START = $(shell layout_parser ${TREZOR_MODEL} KERNEL_START)
-FIRMWARE_START = $(shell layout_parser ${TREZOR_MODEL} FIRMWARE_START)
-FIRMWARE_P2_START = $(shell layout_parser ${TREZOR_MODEL} FIRMWARE_P2_START)
-STORAGE_1_START = $(shell layout_parser ${TREZOR_MODEL} STORAGE_1_START)
-STORAGE_2_START = $(shell layout_parser ${TREZOR_MODEL} STORAGE_2_START)
-STORAGE_SIZE = $(shell layout_parser ${TREZOR_MODEL} NORCOW_SECTOR_SIZE)
-BOARDLOADER_MAXSIZE = $(shell layout_parser ${TREZOR_MODEL} BOARDLOADER_MAXSIZE)
-BOOTLOADER_MAXSIZE = $(shell layout_parser ${TREZOR_MODEL} BOOTLOADER_MAXSIZE)
-FIRMWARE_MAXSIZE = $(shell layout_parser ${TREZOR_MODEL} FIRMWARE_MAXSIZE)
-FIRMWARE_P1_MAXSIZE = $(shell layout_parser ${TREZOR_MODEL} FIRMWARE_P1_MAXSIZE)
-FIRMWARE_P2_MAXSIZE = $(shell layout_parser ${TREZOR_MODEL} FIRMWARE_P2_MAXSIZE)
-BOARDLOADER_SECTOR_START = $(shell layout_parser ${TREZOR_MODEL} BOARDLOADER_SECTOR_START)
-BOARDLOADER_SECTOR_END = $(shell layout_parser ${TREZOR_MODEL} BOARDLOADER_SECTOR_END)
-BOOTLOADER_SECTOR_START = $(shell layout_parser ${TREZOR_MODEL} BOOTLOADER_SECTOR_START)
-BOOTLOADER_SECTOR_END = $(shell layout_parser ${TREZOR_MODEL} BOOTLOADER_SECTOR_END)
-FIRMWARE_SECTOR_START = $(shell layout_parser ${TREZOR_MODEL} FIRMWARE_SECTOR_START)
-FIRMWARE_SECTOR_END = $(shell layout_parser ${TREZOR_MODEL} FIRMWARE_SECTOR_END)
-FIRMWARE_P1_SECTOR_START = $(shell layout_parser ${TREZOR_MODEL} FIRMWARE_P1_SECTOR_START)
-FIRMWARE_P1_SECTOR_END = $(shell layout_parser ${TREZOR_MODEL} FIRMWARE_P1_SECTOR_END)
-FIRMWARE_P2_SECTOR_START = $(shell layout_parser ${TREZOR_MODEL} FIRMWARE_P2_SECTOR_START)
-FIRMWARE_P2_SECTOR_END = $(shell layout_parser ${TREZOR_MODEL} FIRMWARE_P2_SECTOR_END)
-STORAGE_1_SECTOR_START = $(shell layout_parser ${TREZOR_MODEL} STORAGE_1_SECTOR_START)
-STORAGE_1_SECTOR_END = $(shell layout_parser ${TREZOR_MODEL} STORAGE_1_SECTOR_END)
-STORAGE_2_SECTOR_START = $(shell layout_parser ${TREZOR_MODEL} STORAGE_2_SECTOR_START)
-STORAGE_2_SECTOR_END = $(shell layout_parser ${TREZOR_MODEL} STORAGE_2_SECTOR_END)
-
-
-STORAGE_1_OFFSET := $(shell expr $(STORAGE_1_START) - $(FLASH_START))
-STORAGE_2_OFFSET := $(shell expr $(STORAGE_2_START) - $(FLASH_START))
-
-OPENOCD = openocd -f interface/$(OPENOCD_INTERFACE).cfg -c "transport select $(OPENOCD_TRANSPORT)" -f $(OPENOCD_TARGET)
-
-SCM_REVISION := $(shell git rev-parse HEAD)
-CFLAGS += -DSCM_REVISION_SHORT_INIT='{$(shell echo $(SCM_REVISION) | cut -c1-8 | sed 's:\(..\):0x\1,:g')}'
-CFLAGS += -DSCM_REVISION_LONG_INIT='{$(shell echo $(SCM_REVISION) | cut -c9-40 | sed 's:\(..\):0x\1,:g')}'
-CFLAGS += -DSCM_REVISION_XOR1=0
-CFLAGS += -DSCM_REVISION_XOR2=0
-
TESTPATH = $(CURDIR)/../tests
EMU = $(CURDIR)/emu.py
@@ -127,54 +24,54 @@ EMU_TEST = $(EMU) $(EMU_TEST_ARGS) -c
JUNIT_XML ?= $(TESTPATH)/junit.xml
PYTEST = pytest --junitxml=$(JUNIT_XML)
TREZOR_FIDO2_UDP_PORT = 21326
-RUST_TARGET=$(shell rustc -vV | sed -n 's/host: //p')
MULTICORE ?= "auto"
RANDOM=$(shell python -c 'import random; print(random.randint(0, 1000000))')
-SCONS_VARS = \
- BENCHMARK="$(BENCHMARK)" \
- BITCOIN_ONLY="$(BITCOIN_ONLY)" \
- BOOTLOADER_DEVEL="$(BOOTLOADER_DEVEL)" \
- FORCE_BOOTLOADER_UPGRADE="$(FORCE_BOOTLOADER_UPGRADE)" \
- UNSAFE_FW="$(UNSAFE_FW)" \
- CFLAGS="$(CFLAGS)" \
- CMAKELISTS="$(CMAKELISTS)" \
- HW_REVISION="$(HW_REVISION)" \
- LOG_STACK_USAGE="$(LOG_STACK_USAGE)" \
- MICROPY_ENABLE_SOURCE_LINE="$(MICROPY_ENABLE_SOURCE_LINE)" \
- PRODUCTION="$(PRODUCTION)" \
- DEBUGLINK="$(DEBUGLINK)" \
- PYOPT="$(PYOPT)" \
- QUIET_MODE="$(QUIET_MODE)" \
- SCM_REVISION="$(SCM_REVISION)" \
- STORAGE_INSECURE_TESTING_MODE="$(STORAGE_INSECURE_TESTING_MODE)" \
- THP="$(THP)" \
- TREZOR_DISABLE_ANIMATION="$(TREZOR_DISABLE_ANIMATION)" \
- TREZOR_EMULATOR_ASAN="$(ADDRESS_SANITIZER)" \
- TREZOR_EMULATOR_DEBUGGABLE=$(TREZOR_EMULATOR_DEBUGGABLE) \
- TREZOR_MEMPERF="$(TREZOR_MEMPERF)" \
- TREZOR_MODEL="$(TREZOR_MODEL)" \
- UI_PERFORMANCE_OVERLAY="$(UI_PERFORMANCE_OVERLAY)" \
- BLOCK_ON_VCP="$(BLOCK_ON_VCP)" \
- DBG_CONSOLE="$(DBG_CONSOLE)" \
- EXTAPP_SUPPORT="$(EXTAPP_SUPPORT)" \
- N4W1="$(N4W1)"
-
-ifdef DISABLE_OPTIGA
-SCONS_VARS += DISABLE_OPTIGA="$(DISABLE_OPTIGA)"
+# Please only add options used by CI, otherwise just run xtask directly.
+XTASK_BUILD_OPTS = --model $(TREZOR_MODEL)
+ifeq ($(ADDRESS_SANITIZER),1)
+XTASK_BUILD_OPTS += --asan
endif
-
-ifdef DISABLE_TROPIC
-SCONS_VARS += DISABLE_TROPIC="$(DISABLE_TROPIC)"
+ifeq ($(BITCOIN_ONLY),1)
+XTASK_BUILD_OPTS += --btc-only
endif
-
-SCONS_OPTS = -Q -j $(JOBS)
-ifeq ($(QUIET_MODE),1)
-SCONS_OPTS += --quiet
+ifeq ($(BOOTLOADER_DEVEL),1)
+XTASK_BUILD_OPTS += --bootloader-devel
+endif
+ifeq ($(N4W1),1)
+XTASK_BUILD_OPTS += --n4w1
+endif
+ifeq ($(PRODUCTION),1)
+XTASK_BUILD_OPTS += --production
+endif
+ifeq ($(PYOPT),1)
+XTASK_BUILD_OPTS += --pyopt true
+else ifeq ($(PYOPT),0)
+XTASK_BUILD_OPTS += --pyopt false
+XTASK_BUILD_OPTS += --disable-animation
+endif
+ifeq ($(TREZOR_MEMPERF),1)
+XTASK_BUILD_OPTS += --mem-perf
+endif
+ifeq ($(UNSAFE_FW),1)
+XTASK_BUILD_OPTS += --unsafe-fw
endif
-SCONS = scons $(SCONS_OPTS) $(SCONS_VARS)
+ifeq ($(STORAGE_INSECURE_TESTING_MODE),1)
+XTASK_BUILD_OPTS += --storage-insecure-testing-mode
+XTASK_BUILD_OPTS += --disable-tropic true
+XTASK_BUILD_OPTS += --disable-optiga
+else
+ ifeq ($(DISABLE_OPTIGA),1)
+ XTASK_BUILD_OPTS += --disable-optiga
+ endif
+ ifeq ($(DISABLE_TROPIC),1)
+ XTASK_BUILD_OPTS += --disable-tropic true
+ else ifeq ($(DISABLE_TROPIC),0)
+ XTASK_BUILD_OPTS += --disable-tropic false
+ endif
+endif
## help commands:
@@ -189,7 +86,7 @@ vendor: ## update git submodules
## emulator commands:
run: ## run unix port
- cd src ; ../$(UNIX_BUILD_DIR)/trezor-emu-core
+ cd src ; ../$(BUILD_DIR)/firmware-emu
emu: ## run emulator
$(EMU)
@@ -200,10 +97,9 @@ test: ## run unit tests
cd tests ; ./run_tests.sh $(TESTOPTS)
test_rust: ## run rs unit tests
- export BUILD_DIR=$(abspath $(UNIX_BUILD_DIR)) ; \
- cd embed/rust ; cargo test $(TESTOPTS) --target=$(RUST_TARGET) \
- --no-default-features --features $(LAYOUT_FEATURE),power_manager,test \
- -- --test-threads=1 --nocapture
+ false # NOT IMPLEMENTED
+ # xtask test crypto
+ # xtask test all
test_emu_sanity: ## make sure the emulator doesn't crash on startup
timeout -v 10 $(EMU) --disable-animation --headless --temporary-profile --command true
@@ -278,11 +174,11 @@ pyright:
python ../tools/pyright_tool.py
clippy:
- export BUILD_DIR=$(abspath $(UNIX_BUILD_DIR)) ; \
- cd embed/rust-staticlib ; cargo clippy $(TESTOPTS) --all-features --target=$(RUST_TARGET)
+ xtask clippy -e -m $(TREZOR_MODEL) bootloader
+ xtask clippy -e -m $(TREZOR_MODEL) firmware
audit_rust: ## run cargo audit on rust dependencies
- cd embed/rust ; cargo audit
+ cd embed ; cargo audit
## code generation:
@@ -319,246 +215,127 @@ build: build_boardloader build_bootloader build_firmware build_prodtest build_un
build_embed: build_boardloader build_bootloader build_firmware # build boardloader, bootloader, firmware
build_boardloader: ## build boardloader
- $(SCONS) $(BOARDLOADER_BUILD_DIR)/boardloader.bin
+ xtask build boardloader $(XTASK_BUILD_OPTS)
build_bootloader: ## build bootloader
- $(SCONS) $(BOOTLOADER_BUILD_DIR)/bootloader.bin
+ xtask build bootloader $(XTASK_BUILD_OPTS)
build_bootloader_ci: ## build CI device testing bootloader
- $(SCONS) $(BOOTLOADER_CI_BUILD_DIR)/bootloader.bin
+ xtask build bootloader_ci $(XTASK_BUILD_OPTS)
build_bootloader_emu: ## build the unix bootloader emulator
- $(SCONS) $(BOOTLOADER_EMU_BUILD_DIR)/bootloader.elf
+ xtask build bootloader --emulator $(XTASK_BUILD_OPTS)
build_bootloader_emu_debug: ## build the unix bootloader emulator
- $(SCONS) TREZOR_EMULATOR_DEBUGGABLE=1 $(BOOTLOADER_EMU_BUILD_DIR)/bootloader.elf
+ xtask build bootloader --debug true --emulator $(XTASK_BUILD_OPTS)
build_prodtest: ## build production test firmware
- $(SCONS) $(PRODTEST_BUILD_DIR)/prodtest.bin
+ xtask build prodtest $(XTASK_BUILD_OPTS)
build_prodtest_emu: ## build the unix prodtest emulator
- $(SCONS) $(PRODTEST_EMU_BUILD_DIR)/prodtest.elf
+ xtask build prodtest --emulator $(XTASK_BUILD_OPTS)
build_secmon: ## build security monitor image
- $(SCONS) $(SECMON_BUILD_DIR)/secmon.bin
+ xtask build secmon $(XTASK_BUILD_OPTS)
-build_kernel: ## build kernel image
- $(SCONS) $(KERNEL_BUILD_DIR)/kernel.bin
+build_firmware: ## build firmware with frozen modules
+ xtask build firmware $(XTASK_BUILD_OPTS)
-# build secmon locally if BOOTLOADER_DEVEL=1 and UNSAFE_FW=0
-BUILD_LOCAL_SECMON =
-ifeq ($(BOOTLOADER_DEVEL),1)
-ifeq ($(UNSAFE_FW),0)
-BUILD_LOCAL_SECMON = build_secmon
-endif
-endif
-
-build_firmware: MICROPY_ENABLE_SOURCE_LINE ?= 0
-build_firmware: templates build_cross $(BUILD_LOCAL_SECMON) build_kernel ## build firmware with frozen modules
- $(SCONS) $(FIRMWARE_BUILD_DIR)/firmware.bin
-
-build_unix: MICROPY_ENABLE_SOURCE_LINE ?= 1
-build_unix: templates ## build unix port
- $(SCONS) PYOPT=0 $(UNIX_BUILD_DIR)/trezor-emu-core $(UNIX_PORT_OPTS)
-
-build_unix_frozen: MICROPY_ENABLE_SOURCE_LINE ?= 1
-build_unix_frozen: templates build_cross ## build unix port with frozen modules
- $(SCONS) $(UNIX_BUILD_DIR)/trezor-emu-core $(UNIX_PORT_OPTS) TREZOR_EMULATOR_FROZEN=1
+build_unix: ## build unix port
+ xtask build firmware --emulator $(XTASK_BUILD_OPTS)
-build_unix_debug: MICROPY_ENABLE_SOURCE_LINE ?= 1
-build_unix_debug: templates ## build unix port
- $(SCONS) --max-drift=1 $(UNIX_BUILD_DIR)/trezor-emu-core $(UNIX_PORT_OPTS) \
- TREZOR_EMULATOR_ASAN=1 TREZOR_EMULATOR_DEBUGGABLE=1
+build_unix_frozen: ## build unix port with frozen modules
+ xtask build firmware --emulator --frozen $(XTASK_BUILD_OPTS)
-build_cross: ## build mpy-cross port
- INC=-I$(CURDIR)/embed/upymod/mpycross_include/ \
- $(MAKE) -C vendor/micropython/mpy-cross $(CROSS_PORT_OPTS)
+build_unix_debug: ## build unix port
+ xtask build firmware --emulator --asan --debug true $(XTASK_BUILD_OPTS)
## clean commands:
-clean: clean_boardloader clean_bootloader clean_bootloader_emu clean_bootloader_ci \
- clean_prodtest clean_prodtest_emu clean_firmware clean_kernel clean_secmon clean_unix clean_cross ## clean all
- rm -f ".sconsign.dblite"
-
-clean_boardloader: ## clean boardloader build
- rm -rf $(BOARDLOADER_BUILD_DIR)
-
-clean_bootloader: ## clean bootloader build
- rm -rf $(BOOTLOADER_BUILD_DIR)
-
-clean_bootloader_ci: ## clean bootloader_ci build
- rm -rf $(BOOTLOADER_CI_BUILD_DIR)
-
-clean_bootloader_emu: ## clean bootloader_emu build
- rm -rf $(BOOTLOADER_EMU_BUILD_DIR)
-
-clean_prodtest: ## clean prodtest build
- rm -rf $(PRODTEST_BUILD_DIR)
-
-clean_prodtest_emu: ## clean prodtest_emu build
- rm -rf $(PRODTEST_EMU_BUILD_DIR)
-
-clean_secmon: ## clean security monitor build
- rm -rf $(SECMON_BUILD_DIR)
-
-clean_kernel: ## clean kernel build
- rm -rf $(KERNEL_BUILD_DIR)
-
-clean_firmware: ## clean firmware build
- rm -rf $(FIRMWARE_BUILD_DIR) $(RUST_BUILD_DIR)
-
-clean_unix: ## clean unix build
- rm -rf $(UNIX_BUILD_DIR) $(RUST_BUILD_DIR)
-
-clean_cross: ## clean mpy-cross build
- $(MAKE) -C vendor/micropython/mpy-cross clean $(CROSS_PORT_OPTS)
+clean: ## clean all
+ xtask clean
## flash commands:
flash: flash_boardloader flash_bootloader flash_firmware ## flash everything using OpenOCD
-flash_boardloader: $(BOARDLOADER_BUILD_DIR)/boardloader.bin ## flash boardloader using OpenOCD
- $(OPENOCD) -c "init; reset halt; flash write_image erase $< $(BOARDLOADER_START); exit"
-
-flash_bootloader: $(BOOTLOADER_BUILD_DIR)/bootloader.bin ## flash bootloader using OpenOCD
- $(OPENOCD) -c "init; reset halt; flash write_image erase $< $(BOOTLOADER_START); exit"
+flash_boardloader: ## flash boardloader using OpenOCD
+ xtask flash --model $(TREZOR_MODEL) boardloader
-flash_bootloader_ci: $(BOOTLOADER_CI_BUILD_DIR)/bootloader.bin ## flash CI bootloader using OpenOCD
- $(OPENOCD) -c "init; reset halt; flash write_image erase $< $(BOOTLOADER_START); exit"
+flash_bootloader: ## flash bootloader using OpenOCD
+ xtask flash --model $(TREZOR_MODEL) bootloader
-flash_prodtest: $(PRODTEST_BUILD_DIR)/prodtest.bin ## flash prodtest using OpenOCD
- $(OPENOCD) -c "init; reset halt; flash write_image erase $< $(FIRMWARE_START); exit"
+flash_bootloader_ci: ## flash CI bootloader using OpenOCD
+ xtask flash --model $(TREZOR_MODEL) bootloader_ci
-flash_firmware: $(FIRMWARE_BUILD_DIR)/firmware.bin ## flash firmware using OpenOCD
-ifeq ($(MCU),$(filter $(MCU),STM32F4))
- $(OPENOCD) -c "init; reset halt; flash write_image erase $<.p1 $(FIRMWARE_START); flash write_image erase $<.p2 $(FIRMWARE_P2_START); exit"
+flash_prodtest: ## flash prodtest using OpenOCD
+ xtask flash --model $(TREZOR_MODEL) prodtest
-else
- $(OPENOCD) -c "init; reset halt; flash write_image erase $< $(FIRMWARE_START); exit"
-endif
-
-flash_combine: $(PRODTEST_BUILD_DIR)/combined.bin ## flash combined using OpenOCD
- $(OPENOCD) -c "init; reset halt; flash write_image erase $< $(BOARDLOADER_START); exit"
+flash_firmware: ## flash firmware using OpenOCD
+ xtask flash --model $(TREZOR_MODEL) firmware
flash_erase: ## erase all sectors in flash bank 0
- $(OPENOCD) -c "init; reset halt; flash info 0; flash erase_sector 0 0 last; flash erase_check 0; exit"
+ xtask flash-erase --model $(TREZOR_MODEL) all
flash_erase_bootloader: ## erase bootloader
- $(OPENOCD) -c "init; reset halt; flash info 0; flash erase_sector 0 $(BOOTLOADER_SECTOR_START) $(BOOTLOADER_SECTOR_END); exit"
+ xtask flash-erase --model $(TREZOR_MODEL) bootloader
flash_erase_firmware: ## erase bootloader
-ifeq ($(MCU),$(filter $(MCU),STM32F4))
- $(OPENOCD) -c "init; reset halt; flash info 0; flash erase_sector 0 $(FIRMWARE_P1_SECTOR_START) $(FIRMWARE_P1_SECTOR_END); flash erase_sector 0 $(FIRMWARE_P2_SECTOR_START) $(FIRMWARE_P2_SECTOR_END); exit"
-
-else
- $(OPENOCD) -c "init; reset halt; flash info 0; flash erase_sector 0 $(FIRMWARE_SECTOR_START) $(FIRMWARE_SECTOR_END); exit"
-endif
-
-flash_read_storage: ## read storage sectors from flash
- $(OPENOCD) -c "init; reset halt; flash read_bank 0 storage1.data $(STORAGE_1_OFFSET) $(STORAGE_SIZE); flash read_bank 0 storage2.data $(STORAGE_2_OFFSET) $(STORAGE_SIZE); exit"
+ xtask flash-erase --model $(TREZOR_MODEL) firmware
flash_erase_storage: ## erase storage sectors from flash
- $(OPENOCD) -c "init; reset halt; flash erase_sector 0 $(STORAGE_1_SECTOR_START) $(STORAGE_1_SECTOR_END); flash erase_sector 0 $(STORAGE_2_SECTOR_START) $(STORAGE_2_SECTOR_END); exit"
-
-flash_bootloader_jlink: $(BOOTLOADER_BUILD_DIR)/bootloader.bin ## flash bootloader using JLink
- JLinkExe -nogui 1 -commanderscript embed/projects/bootloader/bootloader_flash.jlink
-
-flash_bootloader_ci_jlink: $(BOOTLOADER_CI_BUILD_DIR)/bootloader.bin ## flash CI bootloader using JLink
- JLinkExe -nogui 1 -commanderscript embed/projects/bootloader_ci/bootloader_flash.jlink
-
-flash_firmware_jlink: $(FIRMWARE_BUILD_DIR)/firmware.bin ## flash firmware using JLink. file names must end in .bin for JLink
- cp -f $<.p1 $<.p1.bin
- cp -f $<.p2 $<.p2.bin
- ## pad 2nd part so that FW integrity works after flash
- ## read&compare in flashing will avoid erasing unmodified sectors
- truncate -s $(FIRMWARE_P2_MAXSIZE) $<.p2.bin
- JLinkExe -nogui 1 -commanderscript embed/projects/firmware/firmware_flash.jlink
-
-## openocd debug commands:
-
-openocd: ## start openocd which connects to the device
- $(OPENOCD)
-
-openocd_reset: ## cause a system reset using OpenOCD
- $(OPENOCD) -c "init; reset; exit"
+ xtask flash-erase --model $(TREZOR_MODEL) storage
+
+#flash_bootloader_jlink: $(BUILD_DIR)/bootloader.bin ## flash bootloader using JLink
+# JLinkExe -nogui 1 -commanderscript embed/projects/bootloader/bootloader_flash.jlink
+#
+#flash_bootloader_ci_jlink: $(BUILD_DIR)/bootloader.bin ## flash CI bootloader using JLink
+# JLinkExe -nogui 1 -commanderscript embed/projects/bootloader_ci/bootloader_flash.jlink
+#
+#flash_firmware_jlink: $(BUILD_DIR)/firmware.bin ## flash firmware using JLink. file names must end in .bin for JLink
+# cp -f $<.p1 $<.p1.bin
+# cp -f $<.p2 $<.p2.bin
+# ## pad 2nd part so that FW integrity works after flash
+# ## read&compare in flashing will avoid erasing unmodified sectors
+# truncate -s $(FIRMWARE_P2_MAXSIZE) $<.p2.bin
+# JLinkExe -nogui 1 -commanderscript embed/projects/firmware/firmware_flash.jlink
GDB = arm-none-eabi-gdb --nx -ex 'set remotetimeout unlimited' -ex 'set confirm off' -ex 'target remote 127.0.0.1:3333' -ex 'monitor reset halt'
-gdb_boardloader: $(BOARDLOADER_BUILD_DIR)/boardloader.elf ## start remote gdb session to openocd with boardloader symbols
+gdb_boardloader: $(BUILD_DIR)/boardloader.elf ## start remote gdb session to openocd with boardloader symbols
$(GDB) $<
-gdb_bootloader: $(BOOTLOADER_BUILD_DIR)/bootloader.elf ## start remote gdb session to openocd with bootloader symbols
+gdb_bootloader: $(BUILD_DIR)/bootloader.elf ## start remote gdb session to openocd with bootloader symbols
$(GDB) $<
-gdb_prodtest: $(PRODTEST_BUILD_DIR)/prodtest.elf ## start remote gdb session to openocd with prodtest symbols
+gdb_prodtest: $(BUILD_DIR)/prodtest.elf ## start remote gdb session to openocd with prodtest symbols
$(GDB) $<
-gdb_firmware: $(FIRMWARE_BUILD_DIR)/firmware.elf ## start remote gdb session to openocd with firmware symbols
+gdb_firmware: $(BUILD_DIR)/firmware.elf ## start remote gdb session to openocd with firmware symbols
$(GDB) $<
## misc commands:
bloaty: ## run bloaty size profiler
- bloaty -d symbols -n 0 -s file $(FIRMWARE_BUILD_DIR)/firmware.elf | less
- bloaty -d compileunits -n 0 -s file $(FIRMWARE_BUILD_DIR)/firmware.elf | less
-
-ifeq ($(MCU),$(filter $(MCU),STM32F4))
-sizecheck: ## check sizes of binary files
- test "$(BOARDLOADER_MAXSIZE)" -ge "$(shell wc -c < $(BOARDLOADER_BUILD_DIR)/boardloader.bin)"
- test "$(BOOTLOADER_MAXSIZE)" -ge "$(shell wc -c < $(BOOTLOADER_BUILD_DIR)/bootloader.bin)"
- test "$(FIRMWARE_P1_MAXSIZE)" -ge "$(shell wc -c < $(FIRMWARE_BUILD_DIR)/firmware.bin.p1)"
- test "$(FIRMWARE_P2_MAXSIZE)" -ge "$(shell wc -c < $(FIRMWARE_BUILD_DIR)/firmware.bin.p2)"
- test "$(FIRMWARE_MAXSIZE)" -ge "$(shell wc -c < $(FIRMWARE_BUILD_DIR)/firmware.bin)"
-else ifeq ($(MCU),$(filter $(MCU),STM32U5))
-sizecheck: ## check sizes of binary files
- test "$(BOARDLOADER_MAXSIZE)" -ge "$(shell wc -c < $(BOARDLOADER_BUILD_DIR)/boardloader.bin)"
- test "$(BOOTLOADER_MAXSIZE)" -ge "$(shell wc -c < $(BOOTLOADER_BUILD_DIR)/bootloader.bin)"
- test "$(FIRMWARE_MAXSIZE)" -ge "$(shell wc -c < $(FIRMWARE_BUILD_DIR)/firmware.bin)"
-endif
+ bloaty -d symbols -n 0 -s file $(BUILD_DIR)/firmware.elf | less
+ bloaty -d compileunits -n 0 -s file $(BUILD_DIR)/firmware.elf | less
combine: ## combine boardloader + bootloader + prodtest into one combined image
- combine_firmware \
- $(TREZOR_MODEL) \
- $(PRODTEST_BUILD_DIR)/combined.bin \
- -b BOARDLOADER $(BOARDLOADER_BUILD_DIR)/boardloader.bin \
- -b BOOTLOADER $(BOOTLOADER_BUILD_DIR)/bootloader.bin \
- -b FIRMWARE $(PRODTEST_BUILD_DIR)/prodtest.bin
-
-ifeq ($(MCU),$(filter $(MCU),STM32F4))
-combine_fw: ## combine boardloader + bootloader + firmware into one combined image
- combine_firmware \
- $(TREZOR_MODEL) \
- $(PRODTEST_BUILD_DIR)/combined.bin \
- -b BOARDLOADER $(BOARDLOADER_BUILD_DIR)/boardloader.bin \
- -b BOOTLOADER $(BOOTLOADER_BUILD_DIR)/bootloader.bin \
- -b FIRMWARE $(FIRMWARE_BUILD_DIR)/firmware.bin.p1 \
- -b FIRMWARE_P2 $(FIRMWARE_BUILD_DIR)/firmware.bin.p2
-else ifeq ($(MCU),$(filter $(MCU),STM32U5))
-combine_fw: ## combine boardloader + bootloader + firmware into one combined image
- combine_firmware \
- $(TREZOR_MODEL) \
- $(PRODTEST_BUILD_DIR)/combined.bin \
- -b BOARDLOADER $(BOARDLOADER_BUILD_DIR)/boardloader.bin \
- -b BOOTLOADER $(BOOTLOADER_BUILD_DIR)/bootloader.bin \
- -b FIRMWARE $(FIRMWARE_BUILD_DIR)/firmware.bin
-endif
+ xtask combine --model $(TREZOR_MODEL) prodtest
-combine_to_hex: ## convert combined image to hex format
- arm-none-eabi-objcopy \
- -I binary -O ihex \
- --change-section-address .data=$(BOARDLOADER_START) \
- $(PRODTEST_BUILD_DIR)/combined.bin $(PRODTEST_BUILD_DIR)/combined.hex
+combine_fw: ## combine boardloader + bootloader + firmware into one combined image
+ xtask combine --model $(TREZOR_MODEL) firmware
upload: ## upload firmware using trezorctl
- trezorctl firmware_update -s -f $(FIRMWARE_BUILD_DIR)/firmware.bin
+ xtask upload firmware --model $(TREZOR_MODEL)
upload_prodtest: ## upload prodtest using trezorctl
- trezorctl firmware_update -s -f $(PRODTEST_BUILD_DIR)/prodtest.bin
+ xtask upload prodtest --model $(TREZOR_MODEL)
# Skip the frozen-build rebuild when preprocessed `.i` files are already
# present (e.g. downloaded as a CI artifact); otherwise build first so local
# `make coverage` is self-contained.
-COVERAGE_I_SENTINEL := $(UNIX_BUILD_DIR)/src/trezor/utils.i
+COVERAGE_I_SENTINEL := $(BUILD_DIR)/mpy-files/trezor/utils.i
COVERAGE_BUILD_DEP := $(if $(wildcard $(COVERAGE_I_SENTINEL)),,build_unix_frozen)
coverage: $(COVERAGE_BUILD_DEP) ## generate coverage report
diff --git a/core/Makefile.scons b/core/Makefile.scons
new file mode 100644
index 00000000..debd175f
--- /dev/null
+++ b/core/Makefile.scons
@@ -0,0 +1,572 @@
+
+.PHONY: vendor
+
+# get the number of CPU cores in a "portable" manner
+# (accounting for darwin and big.LITTLE archs)
+JOBS = $(shell sysctl -n hw.perflevel0.physicalcpu 2>/dev/null ||\
+ sysctl -n hw.physicalcpu 2>/dev/null ||\
+ sysctl -n hw.ncpu 2>/dev/null ||\
+ nproc 2>/dev/null ||\
+ echo 4)
+MAKE = make -j $(JOBS)
+
+BUILD_DIR = build
+BOARDLOADER_BUILD_DIR = $(BUILD_DIR)/boardloader
+BOOTLOADER_BUILD_DIR = $(BUILD_DIR)/bootloader
+BOOTLOADER_CI_BUILD_DIR = $(BUILD_DIR)/bootloader_ci
+BOOTLOADER_EMU_BUILD_DIR = $(BUILD_DIR)/bootloader_emu
+PRODTEST_BUILD_DIR = $(BUILD_DIR)/prodtest
+PRODTEST_EMU_BUILD_DIR = $(BUILD_DIR)/prodtest_emu
+KERNEL_BUILD_DIR = $(BUILD_DIR)/kernel
+SECMON_BUILD_DIR = $(BUILD_DIR)/secmon
+FIRMWARE_BUILD_DIR = $(BUILD_DIR)/firmware
+UNIX_BUILD_DIR = $(BUILD_DIR)/unix
+RUST_BUILD_DIR = $(BUILD_DIR)/rust
+
+UNAME_S := $(shell uname -s)
+UNIX_PORT_OPTS ?=
+CROSS_PORT_OPTS ?=
+
+PRODUCTION ?= 0
+DEBUGLINK ?= 0
+PYOPT ?= 1
+BITCOIN_ONLY ?= 0
+FORCE_BOOTLOADER_UPGRADE ?= 0
+BOOTLOADER_DEVEL ?= 0
+UNSAFE_FW ?= 0
+TREZOR_MODEL ?= T3W1
+TREZOR_MEMPERF ?= 0
+ADDRESS_SANITIZER ?= 0
+CMAKELISTS ?= 0
+PYTEST_TIMEOUT ?= 500
+TEST_LANG ?= "en"
+THP ?= $(if $(filter T3W1,$(TREZOR_MODEL)),1,0)
+BENCHMARK ?= 0
+LOG_STACK_USAGE ?= 0
+TREZOR_EMULATOR_DEBUGGABLE ?= 0
+QUIET_MODE ?= 0
+TREZOR_DISABLE_ANIMATION ?= $(if $(filter 0,$(PYOPT)),1,0)
+STORAGE_INSECURE_TESTING_MODE ?= 0
+UI_PERFORMANCE_OVERLAY ?= 0
+DBG_CONSOLE ?=
+EXTAPP_SUPPORT ?= 0
+N4W1 ?= 0
+
+ifeq ($(PRODUCTION),1)
+ifeq ($(BOOTLOADER_DEVEL),1)
+$(error PRODUCTION and BOOTLOADER_DEVEL cannot be set at the same time)
+# remove this check if you know what you are doing and need to build this way
+endif
+endif
+
+# If set, VCP writes will be blocking, in order to allow reliable debug data transmission over VCP.
+# Disabled by default, to prevent debug firmware from getting stuck while writing log messages (if the host is not reading them).
+BLOCK_ON_VCP ?= 0
+
+# OpenOCD interface default. Alternative: ftdi/olimex-arm-usb-tiny-h
+OPENOCD_INTERFACE ?= stlink
+# OpenOCD transport default. Alternative: jtag
+OPENOCD_TRANSPORT ?= hla_swd
+
+# Include the device-specific definitions.
+include embed/models/$(TREZOR_MODEL)/config.mk
+
+# Get bindgen macros for rust tests
+TEST_BINDGEN_MACROS := $(shell tr -d '\n' < embed/models/$(TREZOR_MODEL)/test_bindgen_macros.txt)
+export TEST_BINDGEN_MACROS
+
+
+FLASH_START = $(shell layout_parser ${TREZOR_MODEL} FLASH_START)
+BOARDLOADER_START = $(shell layout_parser ${TREZOR_MODEL} BOARDLOADER_START)
+BOOTLOADER_START = $(shell layout_parser ${TREZOR_MODEL} BOOTLOADER_START)
+KERNEL_START = $(shell layout_parser ${TREZOR_MODEL} KERNEL_START)
+FIRMWARE_START = $(shell layout_parser ${TREZOR_MODEL} FIRMWARE_START)
+FIRMWARE_P2_START = $(shell layout_parser ${TREZOR_MODEL} FIRMWARE_P2_START)
+STORAGE_1_START = $(shell layout_parser ${TREZOR_MODEL} STORAGE_1_START)
+STORAGE_2_START = $(shell layout_parser ${TREZOR_MODEL} STORAGE_2_START)
+STORAGE_SIZE = $(shell layout_parser ${TREZOR_MODEL} NORCOW_SECTOR_SIZE)
+BOARDLOADER_MAXSIZE = $(shell layout_parser ${TREZOR_MODEL} BOARDLOADER_MAXSIZE)
+BOOTLOADER_MAXSIZE = $(shell layout_parser ${TREZOR_MODEL} BOOTLOADER_MAXSIZE)
+FIRMWARE_MAXSIZE = $(shell layout_parser ${TREZOR_MODEL} FIRMWARE_MAXSIZE)
+FIRMWARE_P1_MAXSIZE = $(shell layout_parser ${TREZOR_MODEL} FIRMWARE_P1_MAXSIZE)
+FIRMWARE_P2_MAXSIZE = $(shell layout_parser ${TREZOR_MODEL} FIRMWARE_P2_MAXSIZE)
+BOARDLOADER_SECTOR_START = $(shell layout_parser ${TREZOR_MODEL} BOARDLOADER_SECTOR_START)
+BOARDLOADER_SECTOR_END = $(shell layout_parser ${TREZOR_MODEL} BOARDLOADER_SECTOR_END)
+BOOTLOADER_SECTOR_START = $(shell layout_parser ${TREZOR_MODEL} BOOTLOADER_SECTOR_START)
+BOOTLOADER_SECTOR_END = $(shell layout_parser ${TREZOR_MODEL} BOOTLOADER_SECTOR_END)
+FIRMWARE_SECTOR_START = $(shell layout_parser ${TREZOR_MODEL} FIRMWARE_SECTOR_START)
+FIRMWARE_SECTOR_END = $(shell layout_parser ${TREZOR_MODEL} FIRMWARE_SECTOR_END)
+FIRMWARE_P1_SECTOR_START = $(shell layout_parser ${TREZOR_MODEL} FIRMWARE_P1_SECTOR_START)
+FIRMWARE_P1_SECTOR_END = $(shell layout_parser ${TREZOR_MODEL} FIRMWARE_P1_SECTOR_END)
+FIRMWARE_P2_SECTOR_START = $(shell layout_parser ${TREZOR_MODEL} FIRMWARE_P2_SECTOR_START)
+FIRMWARE_P2_SECTOR_END = $(shell layout_parser ${TREZOR_MODEL} FIRMWARE_P2_SECTOR_END)
+STORAGE_1_SECTOR_START = $(shell layout_parser ${TREZOR_MODEL} STORAGE_1_SECTOR_START)
+STORAGE_1_SECTOR_END = $(shell layout_parser ${TREZOR_MODEL} STORAGE_1_SECTOR_END)
+STORAGE_2_SECTOR_START = $(shell layout_parser ${TREZOR_MODEL} STORAGE_2_SECTOR_START)
+STORAGE_2_SECTOR_END = $(shell layout_parser ${TREZOR_MODEL} STORAGE_2_SECTOR_END)
+
+
+STORAGE_1_OFFSET := $(shell expr $(STORAGE_1_START) - $(FLASH_START))
+STORAGE_2_OFFSET := $(shell expr $(STORAGE_2_START) - $(FLASH_START))
+
+OPENOCD = openocd -f interface/$(OPENOCD_INTERFACE).cfg -c "transport select $(OPENOCD_TRANSPORT)" -f $(OPENOCD_TARGET)
+
+SCM_REVISION := $(shell git rev-parse HEAD)
+CFLAGS += -DSCM_REVISION_SHORT_INIT='{$(shell echo $(SCM_REVISION) | cut -c1-8 | sed 's:\(..\):0x\1,:g')}'
+CFLAGS += -DSCM_REVISION_LONG_INIT='{$(shell echo $(SCM_REVISION) | cut -c9-40 | sed 's:\(..\):0x\1,:g')}'
+CFLAGS += -DSCM_REVISION_XOR1=0
+CFLAGS += -DSCM_REVISION_XOR2=0
+
+TESTPATH = $(CURDIR)/../tests
+
+EMU = $(CURDIR)/emu.py
+EMU_LOG_FILE ?= $(TESTPATH)/trezor.log
+EMU_TEST_ARGS = --disable-animation --headless --output=$(EMU_LOG_FILE) --temporary-profile
+EMU_TEST = $(EMU) $(EMU_TEST_ARGS) -c
+
+JUNIT_XML ?= $(TESTPATH)/junit.xml
+PYTEST = pytest --junitxml=$(JUNIT_XML)
+TREZOR_FIDO2_UDP_PORT = 21326
+RUST_TARGET=$(shell rustc -vV | sed -n 's/host: //p')
+
+MULTICORE ?= "auto"
+RANDOM=$(shell python -c 'import random; print(random.randint(0, 1000000))')
+
+SCONS_VARS = \
+ BENCHMARK="$(BENCHMARK)" \
+ BITCOIN_ONLY="$(BITCOIN_ONLY)" \
+ BOOTLOADER_DEVEL="$(BOOTLOADER_DEVEL)" \
+ FORCE_BOOTLOADER_UPGRADE="$(FORCE_BOOTLOADER_UPGRADE)" \
+ UNSAFE_FW="$(UNSAFE_FW)" \
+ CFLAGS="$(CFLAGS)" \
+ CMAKELISTS="$(CMAKELISTS)" \
+ HW_REVISION="$(HW_REVISION)" \
+ LOG_STACK_USAGE="$(LOG_STACK_USAGE)" \
+ MICROPY_ENABLE_SOURCE_LINE="$(MICROPY_ENABLE_SOURCE_LINE)" \
+ PRODUCTION="$(PRODUCTION)" \
+ DEBUGLINK="$(DEBUGLINK)" \
+ PYOPT="$(PYOPT)" \
+ QUIET_MODE="$(QUIET_MODE)" \
+ SCM_REVISION="$(SCM_REVISION)" \
+ STORAGE_INSECURE_TESTING_MODE="$(STORAGE_INSECURE_TESTING_MODE)" \
+ THP="$(THP)" \
+ TREZOR_DISABLE_ANIMATION="$(TREZOR_DISABLE_ANIMATION)" \
+ TREZOR_EMULATOR_ASAN="$(ADDRESS_SANITIZER)" \
+ TREZOR_EMULATOR_DEBUGGABLE=$(TREZOR_EMULATOR_DEBUGGABLE) \
+ TREZOR_MEMPERF="$(TREZOR_MEMPERF)" \
+ TREZOR_MODEL="$(TREZOR_MODEL)" \
+ UI_PERFORMANCE_OVERLAY="$(UI_PERFORMANCE_OVERLAY)" \
+ BLOCK_ON_VCP="$(BLOCK_ON_VCP)" \
+ DBG_CONSOLE="$(DBG_CONSOLE)" \
+ EXTAPP_SUPPORT="$(EXTAPP_SUPPORT)" \
+ N4W1="$(N4W1)"
+
+ifdef DISABLE_OPTIGA
+SCONS_VARS += DISABLE_OPTIGA="$(DISABLE_OPTIGA)"
+endif
+
+ifdef DISABLE_TROPIC
+SCONS_VARS += DISABLE_TROPIC="$(DISABLE_TROPIC)"
+endif
+
+SCONS_OPTS = -Q -j $(JOBS)
+ifeq ($(QUIET_MODE),1)
+SCONS_OPTS += --quiet
+endif
+
+SCONS = scons $(SCONS_OPTS) $(SCONS_VARS)
+
+## help commands:
+
+help: ## show this help
+ @awk -f ../tools/help.awk $(MAKEFILE_LIST)
+
+## dependencies commands:
+
+vendor: ## update git submodules
+ git submodule update --init --recursive --force
+
+## emulator commands:
+
+run: ## run unix port
+ cd src ; ../$(UNIX_BUILD_DIR)/trezor-emu-core
+
+emu: ## run emulator
+ $(EMU)
+
+## test commands:
+
+test: ## run unit tests
+ cd tests ; ./run_tests.sh $(TESTOPTS)
+
+test_rust: ## run rs unit tests
+ export BUILD_DIR=$(abspath $(UNIX_BUILD_DIR)) ; \
+ cd embed/rust ; cargo test $(TESTOPTS) --target=$(RUST_TARGET) \
+ --no-default-features --features $(LAYOUT_FEATURE),power_manager,test \
+ -- --test-threads=1 --nocapture
+
+test_emu_sanity: ## make sure the emulator doesn't crash on startup
+ timeout -v 10 $(EMU) --disable-animation --headless --temporary-profile --command true
+
+test_emu: ## run selected device tests from python-trezor
+ $(EMU_TEST) $(PYTEST) $(TESTPATH)/device_tests $(TESTOPTS) --lang=$(TEST_LANG)
+
+test_emu_multicore: ## run device tests using multiple cores
+ $(PYTEST) -n $(MULTICORE) $(TESTPATH)/device_tests $(TESTOPTS) --timeout $(PYTEST_TIMEOUT) \
+ --control-emulators --model=core --random-order-seed=$(RANDOM) \
+ --lang=$(TEST_LANG)
+
+test_emu_monero: ## run selected monero device tests from monero-agent
+ cd tests ; $(EMU_TEST) ./run_tests_device_emu_monero.sh $(TESTOPTS)
+
+test_emu_u2f: ## run selected u2f device tests from u2f-tests-hid
+ $(EMU_TEST) --slip0014 $(TESTPATH)/fido_tests/u2f-tests-hid/HIDTest $(TREZOR_FIDO2_UDP_PORT) $(TESTOPTS)
+ $(EMU_TEST) --slip0014 $(TESTPATH)/fido_tests/u2f-tests-hid/U2FTest $(TREZOR_FIDO2_UDP_PORT) $(TESTOPTS)
+
+test_emu_fido2: ## run fido2 device tests
+ cd $(TESTPATH)/fido_tests/fido2 ; \
+ $(EMU_TEST) --slip0014 $(PYTEST) --maxfail=5 --sim tests/standard/ --vendor trezor $(TESTOPTS)
+
+test_emu_click: ## run click tests
+ $(EMU_TEST) $(PYTEST) $(TESTPATH)/click_tests $(TESTOPTS) --lang=$(TEST_LANG)
+
+test_emu_click_ui: ## run click tests with UI testing
+ $(EMU_TEST) $(PYTEST) $(TESTPATH)/click_tests $(TESTOPTS) \
+ --ui=test --ui-check-missing --do-master-diff --lang=$(TEST_LANG)
+
+test_emu_click_ui_multicore: ## run click tests with UI testing using multiple cores
+ $(PYTEST) -n $(MULTICORE) $(TESTPATH)/click_tests $(TESTOPTS) --timeout $(PYTEST_TIMEOUT) \
+ --ui=test --ui-check-missing --do-master-diff --lang=$(TEST_LANG) \
+ --control-emulators --model=core --random-order-seed=$(RANDOM)
+
+test_emu_persistence: ## run persistence tests
+ $(PYTEST) $(TESTPATH)/persistence_tests $(TESTOPTS) --lang=$(TEST_LANG)
+
+test_emu_persistence_ui: ## run persistence tests with UI testing
+ $(PYTEST) $(TESTPATH)/persistence_tests $(TESTOPTS) \
+ --ui=test --ui-check-missing --do-master-diff --lang=$(TEST_LANG)
+
+test_emu_ui: ## run ui integration tests
+ $(EMU_TEST) $(PYTEST) $(TESTPATH)/device_tests $(TESTOPTS) \
+ --ui=test --ui-check-missing --do-master-diff \
+ --lang=$(TEST_LANG)
+
+test_emu_ui_multicore: ## run ui integration tests using multiple cores
+ $(PYTEST) -n $(MULTICORE) $(TESTPATH)/device_tests $(TESTOPTS) --timeout $(PYTEST_TIMEOUT) \
+ --ui=test --ui-check-missing --do-master-diff \
+ --control-emulators --model=core --random-order-seed=$(RANDOM) \
+ --lang=$(TEST_LANG)
+
+test_emu_ui_record: ## record and hash screens for ui integration tests
+ $(EMU_TEST) $(PYTEST) $(TESTPATH)/device_tests $(TESTOPTS) \
+ --ui=record --ui-check-missing --do-master-diff --lang=$(TEST_LANG)
+
+test_emu_ui_record_multicore: ## quickly record all screens
+ make -f Makefile.scons test_emu_ui_multicore || echo "All errors are recorded in fixtures.json"
+ ../tests/update_fixtures.py local --remove-missing
+
+pylint: ## run pylint on application sources and tests
+ pylint -E $(shell find src tests -name *.py)
+
+mypy: ## deprecated; use "make typecheck"
+ @echo "mypy is deprecated; use 'make typecheck'"
+ make -f Makefile.scons typecheck
+
+typecheck: pyright
+
+pyright:
+ python ../tools/pyright_tool.py
+
+clippy:
+ export BUILD_DIR=$(abspath $(UNIX_BUILD_DIR)) ; \
+ cd embed/rust ; cargo clippy $(TESTOPTS) --all-features --target=$(RUST_TARGET)
+
+audit_rust: ## run cargo audit on rust dependencies
+ cd embed/rust ; cargo audit
+
+## code generation:
+
+templates: translations ## render Mako templates (for lists of coins, tokens, etc.)
+ ./tools/build_templates
+
+templates_check: translations_check ## check that Mako-rendered files match their templates
+ ./tools/build_templates --check
+
+translations: ## update translations
+ python ./translations/order.py
+ python ./translations/cli.py gen
+
+translations_check: ## check that translations are up to date
+ python ./translations/order.py --check
+ python ./translations/cli.py gen --check
+ # spits out error if the stored merkle root is not up to date
+ python ./translations/cli.py merkle-root > /dev/null
+
+translations_crowdin_push: translations ## split translations and push to crowdin
+ ## prepare source files from joint `en.json` into split `en_<layout_type>.json`
+ cd translations; python crowdin.py split
+ cd translations; crowdin push sources
+
+translations_crowdin_pull: ## pull translations from crowdin
+ cd translations; crowdin pull --skip-untranslated-strings
+ # prepare joint `<lang>.json` from split `<lang>_<layout_type>.json`
+ cd translations; python crowdin.py merge
+
+## build commands:
+
+build: build_boardloader build_bootloader build_firmware build_prodtest build_unix ## build all
+
+build_embed: build_boardloader build_bootloader build_firmware # build boardloader, bootloader, firmware
+
+build_boardloader: ## build boardloader
+ $(SCONS) $(BOARDLOADER_BUILD_DIR)/boardloader.bin
+
+build_bootloader: ## build bootloader
+ $(SCONS) $(BOOTLOADER_BUILD_DIR)/bootloader.bin
+
+build_bootloader_ci: ## build CI device testing bootloader
+ $(SCONS) $(BOOTLOADER_CI_BUILD_DIR)/bootloader.bin
+
+build_bootloader_emu: ## build the unix bootloader emulator
+ $(SCONS) $(BOOTLOADER_EMU_BUILD_DIR)/bootloader.elf
+
+build_bootloader_emu_debug: ## build the unix bootloader emulator
+ $(SCONS) TREZOR_EMULATOR_DEBUGGABLE=1 $(BOOTLOADER_EMU_BUILD_DIR)/bootloader.elf
+
+build_prodtest: ## build production test firmware
+ $(SCONS) $(PRODTEST_BUILD_DIR)/prodtest.bin
+
+build_prodtest_emu: ## build the unix prodtest emulator
+ $(SCONS) $(PRODTEST_EMU_BUILD_DIR)/prodtest.elf
+
+build_secmon: ## build security monitor image
+ $(SCONS) $(SECMON_BUILD_DIR)/secmon.bin
+
+build_kernel: ## build kernel image
+ $(SCONS) $(KERNEL_BUILD_DIR)/kernel.bin
+
+# build secmon locally if BOOTLOADER_DEVEL=1 and UNSAFE_FW=0
+BUILD_LOCAL_SECMON =
+ifeq ($(BOOTLOADER_DEVEL),1)
+ifeq ($(UNSAFE_FW),0)
+BUILD_LOCAL_SECMON = build_secmon
+endif
+endif
+
+build_firmware: MICROPY_ENABLE_SOURCE_LINE ?= 0
+build_firmware: templates build_cross $(BUILD_LOCAL_SECMON) build_kernel ## build firmware with frozen modules
+ $(SCONS) $(FIRMWARE_BUILD_DIR)/firmware.bin
+
+build_unix: MICROPY_ENABLE_SOURCE_LINE ?= 1
+build_unix: templates ## build unix port
+ $(SCONS) PYOPT=0 $(UNIX_BUILD_DIR)/trezor-emu-core $(UNIX_PORT_OPTS)
+
+build_unix_frozen: MICROPY_ENABLE_SOURCE_LINE ?= 1
+build_unix_frozen: templates build_cross ## build unix port with frozen modules
+ $(SCONS) $(UNIX_BUILD_DIR)/trezor-emu-core $(UNIX_PORT_OPTS) TREZOR_EMULATOR_FROZEN=1
+
+build_unix_debug: MICROPY_ENABLE_SOURCE_LINE ?= 1
+build_unix_debug: templates ## build unix port
+ $(SCONS) --max-drift=1 $(UNIX_BUILD_DIR)/trezor-emu-core $(UNIX_PORT_OPTS) \
+ TREZOR_EMULATOR_ASAN=1 TREZOR_EMULATOR_DEBUGGABLE=1
+
+build_cross: ## build mpy-cross port
+ INC=-I$(CURDIR)/embed/upymod/mpycross_include/ \
+ $(MAKE) -C vendor/micropython/mpy-cross $(CROSS_PORT_OPTS)
+
+## clean commands:
+
+clean: clean_boardloader clean_bootloader clean_bootloader_emu clean_bootloader_ci \
+ clean_prodtest clean_prodtest_emu clean_firmware clean_kernel clean_secmon clean_unix clean_cross ## clean all
+ rm -f ".sconsign.dblite"
+
+clean_boardloader: ## clean boardloader build
+ rm -rf $(BOARDLOADER_BUILD_DIR)
+
+clean_bootloader: ## clean bootloader build
+ rm -rf $(BOOTLOADER_BUILD_DIR)
+
+clean_bootloader_ci: ## clean bootloader_ci build
+ rm -rf $(BOOTLOADER_CI_BUILD_DIR)
+
+clean_bootloader_emu: ## clean bootloader_emu build
+ rm -rf $(BOOTLOADER_EMU_BUILD_DIR)
+
+clean_prodtest: ## clean prodtest build
+ rm -rf $(PRODTEST_BUILD_DIR)
+
+clean_prodtest_emu: ## clean prodtest_emu build
+ rm -rf $(PRODTEST_EMU_BUILD_DIR)
+
+clean_secmon: ## clean security monitor build
+ rm -rf $(SECMON_BUILD_DIR)
+
+clean_kernel: ## clean kernel build
+ rm -rf $(KERNEL_BUILD_DIR)
+
+clean_firmware: ## clean firmware build
+ rm -rf $(FIRMWARE_BUILD_DIR) $(RUST_BUILD_DIR)
+
+clean_unix: ## clean unix build
+ rm -rf $(UNIX_BUILD_DIR) $(RUST_BUILD_DIR)
+
+clean_cross: ## clean mpy-cross build
+ $(MAKE) -C vendor/micropython/mpy-cross clean $(CROSS_PORT_OPTS)
+
+## flash commands:
+
+flash: flash_boardloader flash_bootloader flash_firmware ## flash everything using OpenOCD
+
+flash_boardloader: $(BOARDLOADER_BUILD_DIR)/boardloader.bin ## flash boardloader using OpenOCD
+ $(OPENOCD) -c "init; reset halt; flash write_image erase $< $(BOARDLOADER_START); exit"
+
+flash_bootloader: $(BOOTLOADER_BUILD_DIR)/bootloader.bin ## flash bootloader using OpenOCD
+ $(OPENOCD) -c "init; reset halt; flash write_image erase $< $(BOOTLOADER_START); exit"
+
+flash_bootloader_ci: $(BOOTLOADER_CI_BUILD_DIR)/bootloader.bin ## flash CI bootloader using OpenOCD
+ $(OPENOCD) -c "init; reset halt; flash write_image erase $< $(BOOTLOADER_START); exit"
+
+flash_prodtest: $(PRODTEST_BUILD_DIR)/prodtest.bin ## flash prodtest using OpenOCD
+ $(OPENOCD) -c "init; reset halt; flash write_image erase $< $(FIRMWARE_START); exit"
+
+flash_firmware: $(FIRMWARE_BUILD_DIR)/firmware.bin ## flash firmware using OpenOCD
+ifeq ($(MCU),$(filter $(MCU),STM32F4))
+ $(OPENOCD) -c "init; reset halt; flash write_image erase $<.p1 $(FIRMWARE_START); flash write_image erase $<.p2 $(FIRMWARE_P2_START); exit"
+
+else
+ $(OPENOCD) -c "init; reset halt; flash write_image erase $< $(FIRMWARE_START); exit"
+endif
+
+flash_combine: $(PRODTEST_BUILD_DIR)/combined.bin ## flash combined using OpenOCD
+ $(OPENOCD) -c "init; reset halt; flash write_image erase $< $(BOARDLOADER_START); exit"
+
+flash_erase: ## erase all sectors in flash bank 0
+ $(OPENOCD) -c "init; reset halt; flash info 0; flash erase_sector 0 0 last; flash erase_check 0; exit"
+
+flash_erase_bootloader: ## erase bootloader
+ $(OPENOCD) -c "init; reset halt; flash info 0; flash erase_sector 0 $(BOOTLOADER_SECTOR_START) $(BOOTLOADER_SECTOR_END); exit"
+
+flash_erase_firmware: ## erase bootloader
+ifeq ($(MCU),$(filter $(MCU),STM32F4))
+ $(OPENOCD) -c "init; reset halt; flash info 0; flash erase_sector 0 $(FIRMWARE_P1_SECTOR_START) $(FIRMWARE_P1_SECTOR_END); flash erase_sector 0 $(FIRMWARE_P2_SECTOR_START) $(FIRMWARE_P2_SECTOR_END); exit"
+
+else
+ $(OPENOCD) -c "init; reset halt; flash info 0; flash erase_sector 0 $(FIRMWARE_SECTOR_START) $(FIRMWARE_SECTOR_END); exit"
+endif
+
+flash_read_storage: ## read storage sectors from flash
+ $(OPENOCD) -c "init; reset halt; flash read_bank 0 storage1.data $(STORAGE_1_OFFSET) $(STORAGE_SIZE); flash read_bank 0 storage2.data $(STORAGE_2_OFFSET) $(STORAGE_SIZE); exit"
+
+flash_erase_storage: ## erase storage sectors from flash
+ $(OPENOCD) -c "init; reset halt; flash erase_sector 0 $(STORAGE_1_SECTOR_START) $(STORAGE_1_SECTOR_END); flash erase_sector 0 $(STORAGE_2_SECTOR_START) $(STORAGE_2_SECTOR_END); exit"
+
+flash_bootloader_jlink: $(BOOTLOADER_BUILD_DIR)/bootloader.bin ## flash bootloader using JLink
+ JLinkExe -nogui 1 -commanderscript embed/projects/bootloader/bootloader_flash.jlink
+
+flash_bootloader_ci_jlink: $(BOOTLOADER_CI_BUILD_DIR)/bootloader.bin ## flash CI bootloader using JLink
+ JLinkExe -nogui 1 -commanderscript embed/projects/bootloader_ci/bootloader_flash.jlink
+
+flash_firmware_jlink: $(FIRMWARE_BUILD_DIR)/firmware.bin ## flash firmware using JLink. file names must end in .bin for JLink
+ cp -f $<.p1 $<.p1.bin
+ cp -f $<.p2 $<.p2.bin
+ ## pad 2nd part so that FW integrity works after flash
+ ## read&compare in flashing will avoid erasing unmodified sectors
+ truncate -s $(FIRMWARE_P2_MAXSIZE) $<.p2.bin
+ JLinkExe -nogui 1 -commanderscript embed/projects/firmware/firmware_flash.jlink
+
+## openocd debug commands:
+
+openocd: ## start openocd which connects to the device
+ $(OPENOCD)
+
+openocd_reset: ## cause a system reset using OpenOCD
+ $(OPENOCD) -c "init; reset; exit"
+
+GDB = arm-none-eabi-gdb --nx -ex 'set remotetimeout unlimited' -ex 'set confirm off' -ex 'target remote 127.0.0.1:3333' -ex 'monitor reset halt'
+
+gdb_boardloader: $(BOARDLOADER_BUILD_DIR)/boardloader.elf ## start remote gdb session to openocd with boardloader symbols
+ $(GDB) $<
+
+gdb_bootloader: $(BOOTLOADER_BUILD_DIR)/bootloader.elf ## start remote gdb session to openocd with bootloader symbols
+ $(GDB) $<
+
+gdb_prodtest: $(PRODTEST_BUILD_DIR)/prodtest.elf ## start remote gdb session to openocd with prodtest symbols
+ $(GDB) $<
+
+gdb_firmware: $(FIRMWARE_BUILD_DIR)/firmware.elf ## start remote gdb session to openocd with firmware symbols
+ $(GDB) $<
+
+## misc commands:
+
+bloaty: ## run bloaty size profiler
+ bloaty -d symbols -n 0 -s file $(FIRMWARE_BUILD_DIR)/firmware.elf | less
+ bloaty -d compileunits -n 0 -s file $(FIRMWARE_BUILD_DIR)/firmware.elf | less
+
+ifeq ($(MCU),$(filter $(MCU),STM32F4))
+sizecheck: ## check sizes of binary files
+ test "$(BOARDLOADER_MAXSIZE)" -ge "$(shell wc -c < $(BOARDLOADER_BUILD_DIR)/boardloader.bin)"
+ test "$(BOOTLOADER_MAXSIZE)" -ge "$(shell wc -c < $(BOOTLOADER_BUILD_DIR)/bootloader.bin)"
+ test "$(FIRMWARE_P1_MAXSIZE)" -ge "$(shell wc -c < $(FIRMWARE_BUILD_DIR)/firmware.bin.p1)"
+ test "$(FIRMWARE_P2_MAXSIZE)" -ge "$(shell wc -c < $(FIRMWARE_BUILD_DIR)/firmware.bin.p2)"
+ test "$(FIRMWARE_MAXSIZE)" -ge "$(shell wc -c < $(FIRMWARE_BUILD_DIR)/firmware.bin)"
+else ifeq ($(MCU),$(filter $(MCU),STM32U5))
+sizecheck: ## check sizes of binary files
+ test "$(BOARDLOADER_MAXSIZE)" -ge "$(shell wc -c < $(BOARDLOADER_BUILD_DIR)/boardloader.bin)"
+ test "$(BOOTLOADER_MAXSIZE)" -ge "$(shell wc -c < $(BOOTLOADER_BUILD_DIR)/bootloader.bin)"
+ test "$(FIRMWARE_MAXSIZE)" -ge "$(shell wc -c < $(FIRMWARE_BUILD_DIR)/firmware.bin)"
+endif
+
+combine: ## combine boardloader + bootloader + prodtest into one combined image
+ combine_firmware \
+ $(TREZOR_MODEL) \
+ $(PRODTEST_BUILD_DIR)/combined.bin \
+ -b BOARDLOADER $(BOARDLOADER_BUILD_DIR)/boardloader.bin \
+ -b BOOTLOADER $(BOOTLOADER_BUILD_DIR)/bootloader.bin \
+ -b FIRMWARE $(PRODTEST_BUILD_DIR)/prodtest.bin
+
+ifeq ($(MCU),$(filter $(MCU),STM32F4))
+combine_fw: ## combine boardloader + bootloader + firmware into one combined image
+ combine_firmware \
+ $(TREZOR_MODEL) \
+ $(PRODTEST_BUILD_DIR)/combined.bin \
+ -b BOARDLOADER $(BOARDLOADER_BUILD_DIR)/boardloader.bin \
+ -b BOOTLOADER $(BOOTLOADER_BUILD_DIR)/bootloader.bin \
+ -b FIRMWARE $(FIRMWARE_BUILD_DIR)/firmware.bin.p1 \
+ -b FIRMWARE_P2 $(FIRMWARE_BUILD_DIR)/firmware.bin.p2
+else ifeq ($(MCU),$(filter $(MCU),STM32U5))
+combine_fw: ## combine boardloader + bootloader + firmware into one combined image
+ combine_firmware \
+ $(TREZOR_MODEL) \
+ $(PRODTEST_BUILD_DIR)/combined.bin \
+ -b BOARDLOADER $(BOARDLOADER_BUILD_DIR)/boardloader.bin \
+ -b BOOTLOADER $(BOOTLOADER_BUILD_DIR)/bootloader.bin \
+ -b FIRMWARE $(FIRMWARE_BUILD_DIR)/firmware.bin
+endif
+
+combine_to_hex: ## convert combined image to hex format
+ arm-none-eabi-objcopy \
+ -I binary -O ihex \
+ --change-section-address .data=$(BOARDLOADER_START) \
+ $(PRODTEST_BUILD_DIR)/combined.bin $(PRODTEST_BUILD_DIR)/combined.hex
+
+upload: ## upload firmware using trezorctl
+ trezorctl firmware_update -s -f $(FIRMWARE_BUILD_DIR)/firmware.bin
+
+upload_prodtest: ## upload prodtest using trezorctl
+ trezorctl firmware_update -s -f $(PRODTEST_BUILD_DIR)/prodtest.bin
+
+# Skip the frozen-build rebuild when preprocessed `.i` files are already
+# present (e.g. downloaded as a CI artifact); otherwise build first so local
+# `make coverage` is self-contained.
+COVERAGE_I_SENTINEL := $(UNIX_BUILD_DIR)/src/trezor/utils.i
+COVERAGE_BUILD_DEP := $(if $(wildcard $(COVERAGE_I_SENTINEL)),,build_unix_frozen)
+
+coverage: $(COVERAGE_BUILD_DEP) ## generate coverage report
+ ./tools/coverage-report
+ ./tools/coverage-annotate.py $(shell find . -name '.coverage*.json*') > htmlcov/hits.md
+
+unused: ## find unused micropython code
+ vulture src src/_vulture_ignore.txt --exclude "messages.py,*/enums/*"
+
+
+.PHONY: templates translations templates_check translations_check
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.