Overview of the Trezor's memory layout and memory protection features.
The MCU powering a Trezor is the STM32F205RET. This chip is an ARM core with many peripherals on die including GPIO, SPI, USB, and Flash. Attached to these are the Trezor's buttons, the OLED screen, USB for power and data, and the Trezor's firmware, bootloader, and metadata storage -- including private key material.
The Flash is structured as follows:
32k of Bootloader
32k of Metadata Storage
448k of space for the firmware
When a Trezor is powered up, the bootloader is executed. The bootloader initializes the hardware, checks the signature of the firmware against a signature baked into the bootloader to make sure that the firmware was signed by SatoshiLabs. If it was, then the bootloader cleanly transfers execution to the firmware. If the signature does not match, then a warning stating that the firmware is not official, and the user must select 'OK' before the bootloader transfers control to the firmware.
The memory where the bootloader resides is write protected. The signature that the bootloader checks for cannot be updated.
This is a fine method to alert a user in the case where an Evil firmware were to be inserted without the user's knowledge. The 'unofficial' warning would appear on the screen and the user would know to stop using that device.
The problem is when you want to run a firmware that you compiled yourself. In that case, the Trezor will display the 'unofficial' warning, but your Trezor has a firmware with code that you want to run. You can click 'OK' and have it continue, but you do not have positive confirmation that the Trezor is running your firmware, and not Evil firmware. The device behaves the same way.
When the Trezor powers up, the first thing the MCU checks is the state of the BOOT0 pin. If the pin is low (0), then the MCU boots into System Memory that contains a manufacturer (STM) bootloader that can be used to program chips (DFU Mode). If BOOT0 is high(1), then the MCU boots into application flash memory, which is the beginning of the Trezor bootloader.
In the Trezor circuit, BOOT0 is hardwired to 1, and therefore will always boot into the Trezor bootloader.