diff --git a/docs/legacy/index.md b/docs/legacy/index.md index 49f9c59fc..276e43ee6 100644 --- a/docs/legacy/index.md +++ b/docs/legacy/index.md @@ -110,6 +110,9 @@ trezorctl firmware-update -f build/legacy/firmware/firmware.bin ## Combining bootloader and firmware with various `PRODUCTION` settings, signed/unsigned +This is an issue before firmware 1.11.2, historical versions need to be built according +to this table. + Not all combinations of bootloader and firmware will work. This depends on 3 variables: PRODUCTION of bootloader, PRODUCTION of firmware, whether firmware is signed @@ -118,9 +121,9 @@ 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 | +| 1 | 1 | no | hardfault in startup.S when setting VTOR and stack | | 0 | 1 | no | works, but don't forget to comment out `check_and_replace_bootloader`, otherwise it'll get overwritten | -| 0 | 0 | no | hard fault because header.S doesn't set VTOR and stack right | +| 0 | 0 | no | hard fault because startup.S doesn't set VTOR and stack right | | 1 | 0 | no | works | The other three possibilities with signed firmware and `PRODUCTION!=0` for bootloader/firmware don't exist. diff --git a/legacy/bootloader/.changelog.d/2423.fixed b/legacy/bootloader/.changelog.d/2423.fixed new file mode 100644 index 000000000..7e3c90472 --- /dev/null +++ b/legacy/bootloader/.changelog.d/2423.fixed @@ -0,0 +1 @@ +Better way to debug T1 combinations of debug/production combinations of bootloader and firmware diff --git a/legacy/bootloader/bootloader.c b/legacy/bootloader/bootloader.c index 31c046f45..0dfa42c72 100644 --- a/legacy/bootloader/bootloader.c +++ b/legacy/bootloader/bootloader.c @@ -161,6 +161,12 @@ int main(void) { if (SIG_OK != signed_firmware) { show_unofficial_warning(fingerprint); } +#if !PRODUCTION + // try to avoid bricking board SWD debug by accident + else { + show_halt("Official firmware", "Won't flash on debug device"); + } +#endif if (SIG_OK != check_firmware_hashes(hdr)) { show_halt("Broken firmware", "detected."); diff --git a/legacy/startup.S b/legacy/startup.S index 85478934a..ee847cf00 100644 --- a/legacy/startup.S +++ b/legacy/startup.S @@ -20,9 +20,30 @@ memset_reg: .type reset_handler, STT_FUNC reset_handler: -#if PRODUCTION -// we need to perform this in case an old bootloader (<1.8.0) -// is starting the new firmware, these will be set incorrectly +// We need to perform VTOR+stack setup case an old bootloader (<1.8.0) +// is starting the new firmware, these will be set incorrectly. + +// To make development easier, set only if we are in privileged +// mode. This resolves annoying combinations of PRODUCTION +// settings for bootloader and FW. +// Normally only signed firmware will let bootloader start FW +// in privileged mode (PRODUCTION=1 variants with signed everything). +// But with devel bootloader we let FW start in privileged mode +// and let's do the check if we can set VTOR without fault + +// Since this startup code is shared with bootloader and FW, +// a) in case of bootloader MCU starts in privileged mode, +// so the jump to "setup_as_unprivileged" never happens. +// VTOR and stack are set from MCU startup +// b) in case of FW it will attempt to set VTOR and stack +// which will work for both signed bootloader+FW, but +// also for other variants with debug bootloader and +// unsigned FW or official bootloader and usigned FW + mrs r3, control + and r3, r3, #1 + cmp r3, #1 + beq .setup_as_unprivileged + ldr r0, =0xE000ED08 // r0 = VTOR address ldr r1, =0x08010400 // r1 = FLASH_APP_START str r1, [r0] // assign @@ -30,8 +51,8 @@ reset_handler: msr msp, r0 // set stack pointer dsb isb -#endif + .setup_as_unprivileged: ldr r0, =_stay_in_bootloader_flag_addr // r0 - address of storage for "stay in bootloader" flag ldr r11, [r0] // r11 - keep in register and hope it gets to main