mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-22 15:38:11 +00:00
bootloader+loader: rework build, make clear what is bootloader and what is loader in docu
This commit is contained in:
parent
cc525e97ce
commit
cbaca604f3
4
Makefile
4
Makefile
@ -29,9 +29,13 @@ build_firmware_debug: vendor res build_cross ## build firmware with frozen modul
|
|||||||
$(MAKE) -f Makefile.firmware $(TREZORHAL_PORT_OPTS) DEBUG=1
|
$(MAKE) -f Makefile.firmware $(TREZORHAL_PORT_OPTS) DEBUG=1
|
||||||
|
|
||||||
build_bootloader: vendor ## build bootloader
|
build_bootloader: vendor ## build bootloader
|
||||||
|
mkdir -p $(BOOTLOADER_BUILD_DIR)/genhdr
|
||||||
|
touch $(BOOTLOADER_BUILD_DIR)/genhdr/qstrdefs.generated.h
|
||||||
$(MAKE) -f Makefile.bootloader $(TREZORHAL_PORT_OPTS)
|
$(MAKE) -f Makefile.bootloader $(TREZORHAL_PORT_OPTS)
|
||||||
|
|
||||||
build_loader: vendor ## build loader
|
build_loader: vendor ## build loader
|
||||||
|
mkdir -p $(LOADER_BUILD_DIR)/genhdr
|
||||||
|
touch $(LOADER_BUILD_DIR)/genhdr/qstrdefs.generated.h
|
||||||
$(MAKE) -f Makefile.loader $(TREZORHAL_PORT_OPTS)
|
$(MAKE) -f Makefile.loader $(TREZORHAL_PORT_OPTS)
|
||||||
|
|
||||||
build_unix: vendor ## build unix port
|
build_unix: vendor ## build unix port
|
||||||
|
@ -1,46 +1,47 @@
|
|||||||
# TREZOR Core Bootloader
|
# TREZOR Core Bootloader
|
||||||
|
|
||||||
Bootloader is split into two stages. See [Memory Layout](memory.md) for info about in which sectors each stage is stored.
|
TREZOR initialization in split into two stages. See [Memory Layout](memory.md) for info about in which sectors each stage is stored.
|
||||||
|
|
||||||
First stage is stored in write-protected area, which means it is non-upgradable. Only second stage bootloader update is allowed.
|
First stage (bootloader) is stored in write-protected area, which means it is non-upgradable.
|
||||||
|
Only second stage (loader) update is allowed.
|
||||||
|
|
||||||
## First Stage Bootloader
|
## First Stage - Bootloader
|
||||||
|
|
||||||
First stage checks the integrity and signatures of the second stage and runs it if everything is OK.
|
First stage checks the integrity and signatures of the second stage and runs it if everything is OK.
|
||||||
|
|
||||||
If first stage bootloader finds a valid second stage bootloader image on the SD card (in raw format, no filesystem),
|
If first stage bootloader finds a valid second stage loader image on the SD card (in raw format, no filesystem),
|
||||||
it will replace the internal second stage, allowing a second stage update via SD card.
|
it will replace the internal second stage, allowing a second stage update via SD card.
|
||||||
|
|
||||||
## Second Stage Bootloader
|
## Second Stage - Loader
|
||||||
|
|
||||||
Second stage checks the integrity and signatures of the firmware and runs it if everything is OK.
|
Second stage checks the integrity and signatures of the firmware and runs it if everything is OK.
|
||||||
|
|
||||||
If second stage bootloader detects a pressed finger on the display or there is no firmware loaded in the device,
|
If second stage loader detects a pressed finger on the display or there is no firmware loaded in the device,
|
||||||
it will start in a firmware update mode, allowing a firmware update via USB.
|
it will start in a firmware update mode, allowing a firmware update via USB.
|
||||||
|
|
||||||
## Common notes
|
## Common notes
|
||||||
|
|
||||||
* Hash function used below is SHA-256 and signature system is Ed25519 (allows combining signatures by multiple keys into one).
|
* Hash function used below is SHA-256 and signature system is Ed25519 (allows combining signatures by multiple keys into one).
|
||||||
* All multibyte integer values are little endian.
|
* All multibyte integer values are little endian.
|
||||||
* There is a tool called [firmwarectl](../tools/firmwarectl) which checks validity of the bootloader/firmware images including their headers.
|
* There is a tool called [firmwarectl](../tools/firmwarectl) which checks validity of the loader/firmware images including their headers.
|
||||||
|
|
||||||
## Bootloader Format
|
## Loader Format
|
||||||
|
|
||||||
TREZOR Core (second stage) bootloader consists of 2 parts:
|
TREZOR Core (second stage) loader consists of 2 parts:
|
||||||
|
|
||||||
1. bootloader header
|
1. loader header
|
||||||
2. bootloader code
|
2. loader code
|
||||||
|
|
||||||
### Bootloader Header
|
### Loader Header
|
||||||
|
|
||||||
Total length of bootloader header is always 256 bytes.
|
Total length of loader header is always 256 bytes.
|
||||||
|
|
||||||
| offset | length | name | description |
|
| offset | length | name | description |
|
||||||
|-------:|-------:|------|-------------|
|
|-------:|-------:|------|-------------|
|
||||||
| 0x0000 | 4 | magic | firmware magic `TRZB` |
|
| 0x0000 | 4 | magic | firmware magic `TRZL` |
|
||||||
| 0x0004 | 4 | hdrlen | length of the bootloader header |
|
| 0x0004 | 4 | hdrlen | length of the loader header |
|
||||||
| 0x0008 | 4 | expiry | valid until timestamp (0=infinity) |
|
| 0x0008 | 4 | expiry | valid until timestamp (0=infinity) |
|
||||||
| 0x000C | 4 | codelen | length of the bootloader code (without the header) |
|
| 0x000C | 4 | codelen | length of the loader code (without the header) |
|
||||||
| 0x0010 | 1 | vmajor | version (major) |
|
| 0x0010 | 1 | vmajor | version (major) |
|
||||||
| 0x0011 | 1 | vminor | version (minor) |
|
| 0x0011 | 1 | vminor | version (minor) |
|
||||||
| 0x0012 | 1 | vpatch | version (patch) |
|
| 0x0012 | 1 | vpatch | version (patch) |
|
||||||
@ -100,7 +101,7 @@ Total length of firmware header is always 256 bytes.
|
|||||||
|
|
||||||
## Various ideas
|
## Various ideas
|
||||||
|
|
||||||
* Bootloader should be able to read vendor+firmware header and send info about FW to client in features message.
|
* Loader should be able to read vendor + firmware header and send info about FW to client in features message.
|
||||||
* Bootloader should not try to run firmware if there is not any.
|
* Loader should not try to run firmware if there is not any.
|
||||||
* Storage wiping rule: Don't erase storage when old FW and new FW are signed using the same key set. Otherwise erase.
|
* Storage wiping rule: Don't erase storage when old FW and new FW are signed using the same key set. Otherwise erase.
|
||||||
* Bootloader should send error to client when firmware update fails and allow client to try one more time. This prevents storage area erasure by accident.
|
* Loader should send error to client when firmware update fails and allow client to try one more time. This prevents storage area erasure by accident.
|
||||||
|
@ -4,11 +4,11 @@
|
|||||||
|
|
||||||
| sector | range | size | function
|
| sector | range | size | function
|
||||||
|-----------|-------------------------|--------:|----------------------
|
|-----------|-------------------------|--------:|----------------------
|
||||||
| Sector 0 | 0x08000000 - 0x08003FFF | 16 KiB | bootloader 1st stage (write-protected)
|
| Sector 0 | 0x08000000 - 0x08003FFF | 16 KiB | bootloader (1st stage) (write-protected)
|
||||||
| Sector 1 | 0x08004000 - 0x08007FFF | 16 KiB | bootloader 1st stage (write-protected)
|
| Sector 1 | 0x08004000 - 0x08007FFF | 16 KiB | bootloader (1st stage) (write-protected)
|
||||||
| Sector 2 | 0x08008000 - 0x0800BFFF | 16 KiB | storage area
|
| Sector 2 | 0x08008000 - 0x0800BFFF | 16 KiB | storage area
|
||||||
| Sector 3 | 0x0800C000 - 0x0800FFFF | 16 KiB | storage area
|
| Sector 3 | 0x0800C000 - 0x0800FFFF | 16 KiB | storage area
|
||||||
| Sector 4 | 0x08010000 - 0x0801FFFF | 64 KiB | bootloader 2nd stage
|
| Sector 4 | 0x08010000 - 0x0801FFFF | 64 KiB | loader (2nd stage)
|
||||||
| Sector 5 | 0x08020000 - 0x0803FFFF | 128 KiB | firmware
|
| Sector 5 | 0x08020000 - 0x0803FFFF | 128 KiB | firmware
|
||||||
| Sector 6 | 0x08040000 - 0x0805FFFF | 128 KiB | firmware
|
| Sector 6 | 0x08040000 - 0x0805FFFF | 128 KiB | firmware
|
||||||
| Sector 7 | 0x08060000 - 0x0807FFFF | 128 KiB | firmware
|
| Sector 7 | 0x08060000 - 0x0807FFFF | 128 KiB | firmware
|
||||||
|
@ -11,7 +11,7 @@ bool parse_header(const uint8_t *data, uint32_t *codelen, uint8_t *sigidx, uint8
|
|||||||
{
|
{
|
||||||
uint32_t magic;
|
uint32_t magic;
|
||||||
memcpy(&magic, data, 4);
|
memcpy(&magic, data, 4);
|
||||||
if (magic != 0x425A5254) return false; // TRZB
|
if (magic != 0x4C5A5254) return false; // TRZL
|
||||||
|
|
||||||
uint32_t hdrlen;
|
uint32_t hdrlen;
|
||||||
memcpy(&hdrlen, data + 4, 4);
|
memcpy(&hdrlen, data + 4, 4);
|
||||||
|
Loading…
Reference in New Issue
Block a user