mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-12 18:49:07 +00:00
rename loader to bootloader
This commit is contained in:
parent
0633506166
commit
0c060b6d4a
@ -20,7 +20,7 @@ script:
|
||||
|
||||
- make build_boardloader
|
||||
|
||||
- make build_loader
|
||||
- make build_bootloader
|
||||
|
||||
- make build_firmware
|
||||
|
||||
|
24
Makefile
24
Makefile
@ -4,7 +4,7 @@ JOBS=4
|
||||
MAKE=make -j $(JOBS)
|
||||
|
||||
BOARDLOADER_BUILD_DIR=micropython/boardloader/build
|
||||
LOADER_BUILD_DIR=micropython/loader/build
|
||||
BOOTLOADER_BUILD_DIR=micropython/bootloader/build
|
||||
FIRMWARE_BUILD_DIR=micropython/firmware/build
|
||||
|
||||
TREZORHAL_PORT_OPTS=FROZEN_MPY_DIR=src DEBUG=1
|
||||
@ -42,14 +42,14 @@ testpy: ## run selected unit tests from python-trezor
|
||||
|
||||
## build commands:
|
||||
|
||||
build: build_boardloader build_loader build_firmware build_unix build_cross ## build all
|
||||
build: build_boardloader build_bootloader build_firmware build_unix build_cross ## build all
|
||||
|
||||
build_boardloader: ## build boardloader
|
||||
$(MAKE) -f Makefile.boardloader $(TREZORHAL_PORT_OPTS)
|
||||
|
||||
build_loader: ## build loader
|
||||
$(MAKE) -f Makefile.loader $(TREZORHAL_PORT_OPTS)
|
||||
./tools/binctl micropython/loader/build/loader.bin -s 1 4141414141414141414141414141414141414141414141414141414141414141
|
||||
build_bootloader: ## build bootloader
|
||||
$(MAKE) -f Makefile.bootloader $(TREZORHAL_PORT_OPTS)
|
||||
./tools/binctl micropython/bootloader/build/bootloader.bin -s 1 4141414141414141414141414141414141414141414141414141414141414141
|
||||
|
||||
build_firmware: res build_cross ## build firmware with frozen modules
|
||||
$(MAKE) -f Makefile.firmware $(TREZORHAL_PORT_OPTS)
|
||||
@ -63,13 +63,13 @@ build_cross: ## build mpy-cross port
|
||||
|
||||
## clean commands:
|
||||
|
||||
clean: clean_boardloader clean_loader clean_firmware clean_unix clean_cross ## clean all
|
||||
clean: clean_boardloader clean_bootloader clean_firmware clean_unix clean_cross ## clean all
|
||||
|
||||
clean_boardloader: ## clean boardloader build
|
||||
$(MAKE) -f Makefile.boardloader clean $(TREZORHAL_PORT_OPTS)
|
||||
|
||||
clean_loader: ## clean loader build
|
||||
$(MAKE) -f Makefile.loader clean $(TREZORHAL_PORT_OPTS)
|
||||
clean_bootloader: ## clean bootloader build
|
||||
$(MAKE) -f Makefile.bootloader clean $(TREZORHAL_PORT_OPTS)
|
||||
|
||||
clean_firmware: ## clean firmware build
|
||||
$(MAKE) -f Makefile.firmware clean $(TREZORHAL_PORT_OPTS)
|
||||
@ -84,13 +84,13 @@ clean_cross: ## clean mpy-cross build
|
||||
|
||||
## flash commands:
|
||||
|
||||
flash: flash_boardloader flash_loader flash_firmware ## flash everything using st-flash
|
||||
flash: flash_boardloader flash_bootloader flash_firmware ## flash everything using st-flash
|
||||
|
||||
flash_boardloader: ## flash boardloader using st-flash
|
||||
st-flash write $(BOARDLOADER_BUILD_DIR)/boardloader.bin 0x08000000
|
||||
|
||||
flash_loader: ## flash loader using st-flash
|
||||
st-flash write $(LOADER_BUILD_DIR)/loader.bin 0x08010000
|
||||
flash_bootloader: ## flash bootloader using st-flash
|
||||
st-flash write $(BOOTLOADER_BUILD_DIR)/bootloader.bin 0x08010000
|
||||
|
||||
flash_firmware: ## flash firmware using st-flash
|
||||
st-flash write $(FIRMWARE_BUILD_DIR)/firmware.bin 0x08020000
|
||||
@ -110,7 +110,7 @@ vendorheader: ## construct default vendor header
|
||||
./tools/binctl micropython/firmware/vendorheader.bin -s 1 4141414141414141414141414141414141414141414141414141414141414141
|
||||
|
||||
binctl: ## print info about binary files
|
||||
./tools/binctl micropython/loader/build/loader.bin
|
||||
./tools/binctl micropython/bootloader/build/bootloader.bin
|
||||
./tools/binctl micropython/firmware/vendorheader.bin
|
||||
./tools/binctl micropython/firmware/build/firmware.bin
|
||||
|
||||
|
@ -3,8 +3,8 @@ SRCDIR_MP = vendor/micropython
|
||||
SRCDIR_FW = micropython
|
||||
|
||||
# target directory
|
||||
BUILD ?= micropython/loader/build
|
||||
TARGET ?= loader
|
||||
BUILD ?= micropython/bootloader/build
|
||||
TARGET ?= bootloader
|
||||
|
||||
# include py core make definitions
|
||||
include $(SRCDIR_MP)/py/mkenv.mk
|
||||
@ -56,8 +56,8 @@ OBJ_HAL += $(addprefix $(BUILD_MP)/,\
|
||||
|
||||
# OBJ micropython/
|
||||
OBJ_FW += $(addprefix $(BUILD_FW)/, \
|
||||
loader/header.o \
|
||||
loader/main.o \
|
||||
bootloader/header.o \
|
||||
bootloader/main.o \
|
||||
extmod/modtrezorui/display.o \
|
||||
extmod/modtrezorui/inflate.o \
|
||||
extmod/modtrezorui/font_bitmap.o \
|
||||
@ -105,7 +105,7 @@ SRC_MOD = $(patsubst $(BUILD_FW)%.o, $(SRCDIR_FW)%.c, $(OBJ_MOD))
|
||||
CROSS_COMPILE = arm-none-eabi-
|
||||
|
||||
INC += -I.
|
||||
INC += -I$(SRCDIR_FW)/loader
|
||||
INC += -I$(SRCDIR_FW)/bootloader
|
||||
INC += -I$(SRCDIR_FW)/extmod/modtrezorui
|
||||
INC += -I$(SRCDIR_FW)/trezorhal
|
||||
INC += -I$(SRCDIR_FW)/trezorhal/hal
|
||||
@ -131,7 +131,7 @@ CFLAGS += -DSTM32_HAL_H='<stm32f4xx_hal.h>'
|
||||
|
||||
LIBS = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
|
||||
|
||||
LDFLAGS = -nostdlib -T $(SRCDIR_FW)/loader/memory.ld -Map=$@.map --cref
|
||||
LDFLAGS = -nostdlib -T $(SRCDIR_FW)/bootloader/memory.ld -Map=$@.map --cref
|
||||
|
||||
# remove uncalled code from the final image
|
||||
CFLAGS += -fdata-sections -ffunction-sections
|
@ -3,20 +3,20 @@
|
||||
TREZOR initialization in split into two stages. See [Memory Layout](memory.md) for info about in which sectors each stage is stored.
|
||||
|
||||
First stage (boardloader) is stored in write-protected area, which means it is non-upgradable.
|
||||
Only second stage (loader) update is allowed.
|
||||
Only second stage (bootloader) update is allowed.
|
||||
|
||||
## First Stage - Boardloader
|
||||
|
||||
First stage checks the integrity and signatures of the second stage and runs it if everything is OK.
|
||||
|
||||
If first stage boardloader finds a valid second stage loader image on the SD card (in raw format, no filesystem),
|
||||
If first stage boardloader finds a valid second stage bootloader 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.
|
||||
|
||||
## Second Stage - Loader
|
||||
## Second Stage - Bootloader
|
||||
|
||||
Second stage checks the integrity and signatures of the firmware and runs it if everything is OK.
|
||||
|
||||
If second stage loader detects a pressed finger on the display or there is no firmware loaded in the device,
|
||||
If second stage bootloader 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.
|
||||
|
||||
## Common notes
|
||||
@ -24,25 +24,25 @@ it will start in a firmware update mode, allowing a firmware update via USB.
|
||||
* Hash function used for computing data digest for signatures is BLAKE2s.
|
||||
* Signature system is Ed25519 (allows combining signatures by multiple keys into one).
|
||||
* All multibyte integer values are little endian.
|
||||
* There is a tool called [binctl](../tools/binctl) which checks validity of the loader/firmware images including their headers.
|
||||
* There is a tool called [binctl](../tools/binctl) which checks validity of the bootloader/firmware images including their headers.
|
||||
|
||||
## Loader Format
|
||||
## Bootloader Format
|
||||
|
||||
TREZOR Core (second stage) loader consists of 2 parts:
|
||||
TREZOR Core (second stage) bootloader consists of 2 parts:
|
||||
|
||||
1. loader header
|
||||
2. loader code
|
||||
1. bootloader header
|
||||
2. bootloader code
|
||||
|
||||
### Loader Header
|
||||
### Bootloader Header
|
||||
|
||||
Total length of loader header is always 512 bytes.
|
||||
Total length of bootloader header is always 512 bytes.
|
||||
|
||||
| offset | length | name | description |
|
||||
|-------:|-------:|------|-------------|
|
||||
| 0x0000 | 4 | magic | firmware magic `TRZL` |
|
||||
| 0x0004 | 4 | hdrlen | length of the loader header |
|
||||
| 0x0000 | 4 | magic | firmware magic `TRZB` |
|
||||
| 0x0004 | 4 | hdrlen | length of the bootloader header |
|
||||
| 0x0008 | 4 | expiry | valid until timestamp (0=infinity) |
|
||||
| 0x000C | 4 | codelen | length of the loader code (without the header) |
|
||||
| 0x000C | 4 | codelen | length of the bootloader code (without the header) |
|
||||
| 0x0010 | 1 | vmajor | version (major) |
|
||||
| 0x0011 | 1 | vminor | version (minor) |
|
||||
| 0x0012 | 1 | vpatch | version (patch) |
|
||||
@ -103,7 +103,7 @@ Total length of firmware header is always 512 bytes.
|
||||
|
||||
## Various ideas
|
||||
|
||||
* Loader should be able to read vendor + firmware header and send info about FW to client in features message.
|
||||
* Loader should not try to run firmware if there is not any.
|
||||
* Bootloader 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.
|
||||
* Storage wiping rule: Don't erase storage when old FW and new FW are signed using the same key set. Otherwise erase.
|
||||
* 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.
|
||||
* 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.
|
||||
|
@ -8,7 +8,7 @@
|
||||
| Sector 1 | 0x08004000 - 0x08007FFF | 16 KiB | boardloader (1st stage) (write-protected)
|
||||
| Sector 2 | 0x08008000 - 0x0800BFFF | 16 KiB | storage area
|
||||
| Sector 3 | 0x0800C000 - 0x0800FFFF | 16 KiB | storage area
|
||||
| Sector 4 | 0x08010000 - 0x0801FFFF | 64 KiB | loader (2nd stage)
|
||||
| Sector 4 | 0x08010000 - 0x0801FFFF | 64 KiB | bootloader (2nd stage)
|
||||
| Sector 5 | 0x08020000 - 0x0803FFFF | 128 KiB | firmware
|
||||
| Sector 6 | 0x08040000 - 0x0805FFFF | 128 KiB | firmware
|
||||
| Sector 7 | 0x08060000 - 0x0807FFFF | 128 KiB | firmware
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include "sdcard.h"
|
||||
#include "version.h"
|
||||
|
||||
#define IMAGE_MAGIC 0x4C5A5254 // TRZL
|
||||
#define IMAGE_MAGIC 0x425A5254 // TRZB
|
||||
#define IMAGE_MAXSIZE (1 * 64 * 1024 + 7 * 128 * 1024)
|
||||
|
||||
void pendsv_isr_handler(void) {
|
||||
@ -76,11 +76,11 @@ bool copy_sdcard(void)
|
||||
}
|
||||
DPRINTLN(" done");
|
||||
|
||||
DPRINTLN("copying new loader from SD card");
|
||||
DPRINTLN("copying new bootloader from SD card");
|
||||
|
||||
sdcard_power_on();
|
||||
|
||||
// copy loader from SD card to Flash
|
||||
// copy bootloader from SD card to Flash
|
||||
uint32_t buf[SDCARD_BLOCK_SIZE / sizeof(uint32_t)];
|
||||
sdcard_read_blocks((uint8_t *)buf, 0, 1);
|
||||
|
||||
@ -95,7 +95,7 @@ bool copy_sdcard(void)
|
||||
for (int i = 0; i < (HEADER_SIZE + hdr.codelen) / SDCARD_BLOCK_SIZE; i++) {
|
||||
sdcard_read_blocks((uint8_t *)buf, i, 1);
|
||||
for (int j = 0; j < SDCARD_BLOCK_SIZE / sizeof(uint32_t); j++) {
|
||||
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, LOADER_START + i * SDCARD_BLOCK_SIZE + j * sizeof(uint32_t), buf[j]) != HAL_OK) {
|
||||
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, BOOTLOADER_START + i * SDCARD_BLOCK_SIZE + j * sizeof(uint32_t), buf[j]) != HAL_OK) {
|
||||
DPRINTLN("copy failed");
|
||||
sdcard_power_off();
|
||||
HAL_FLASH_Lock();
|
||||
@ -114,29 +114,29 @@ bool copy_sdcard(void)
|
||||
|
||||
void check_and_jump(void)
|
||||
{
|
||||
DPRINTLN("checking loader");
|
||||
DPRINTLN("checking bootloader");
|
||||
|
||||
image_header hdr;
|
||||
|
||||
if (image_parse_header((const uint8_t *)LOADER_START, IMAGE_MAGIC, IMAGE_MAXSIZE, &hdr)) {
|
||||
DPRINTLN("valid loader header");
|
||||
if (image_parse_header((const uint8_t *)BOOTLOADER_START, IMAGE_MAGIC, IMAGE_MAXSIZE, &hdr)) {
|
||||
DPRINTLN("valid bootloader header");
|
||||
} else {
|
||||
DPRINTLN("invalid loader header");
|
||||
DPRINTLN("invalid bootloader header");
|
||||
return;
|
||||
}
|
||||
|
||||
if (image_check_signature((const uint8_t *)LOADER_START, &hdr, NULL)) {
|
||||
DPRINTLN("valid loader signature");
|
||||
if (image_check_signature((const uint8_t *)BOOTLOADER_START, &hdr, NULL)) {
|
||||
DPRINTLN("valid bootloader signature");
|
||||
|
||||
// TODO: remove debug wait
|
||||
DPRINTLN("waiting 1 second");
|
||||
HAL_Delay(1000);
|
||||
// end
|
||||
DPRINTLN("JUMP!");
|
||||
jump_to(LOADER_START + HEADER_SIZE);
|
||||
jump_to(BOOTLOADER_START + HEADER_SIZE);
|
||||
|
||||
} else {
|
||||
DPRINTLN("invalid loader signature");
|
||||
DPRINTLN("invalid bootloader signature");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
.size g_header, .-g_header
|
||||
|
||||
g_header:
|
||||
.byte 'T','R','Z','L' // magic
|
||||
.byte 'T','R','Z','B' // magic
|
||||
.word g_header_end - g_header // hdrlen
|
||||
.word 0 // expiry
|
||||
.word _codelen // codelen
|
@ -178,9 +178,9 @@ int main(void)
|
||||
display_clear();
|
||||
display_backlight(255);
|
||||
|
||||
DPRINTLN("TREZOR Loader " VERSION_STR);
|
||||
DPRINTLN("=============");
|
||||
DPRINTLN("starting loader");
|
||||
DPRINTLN("TREZOR Bootloader " VERSION_STR);
|
||||
DPRINTLN("=================");
|
||||
DPRINTLN("starting bootloader");
|
||||
|
||||
if (touch_read() != 0) {
|
||||
mainloop();
|
@ -4,7 +4,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#define BOARDLOADER_START 0x08000000
|
||||
#define LOADER_START 0x08010000
|
||||
#define BOOTLOADER_START 0x08010000
|
||||
#define FIRMWARE_START 0x08020000
|
||||
#define HEADER_SIZE 0x200
|
||||
|
||||
|
14
tools/binctl
14
tools/binctl
@ -16,7 +16,7 @@ def format_sigmask(sigmask):
|
||||
return '0x%02x = [%s]' % (sigmask, ' '.join(bits))
|
||||
|
||||
|
||||
# loader/firmware headers specification: https://github.com/trezor/trezor-core/blob/master/docs/bootloader.md
|
||||
# bootloader/firmware headers specification: https://github.com/trezor/trezor-core/blob/master/docs/bootloader.md
|
||||
|
||||
|
||||
class BinImage:
|
||||
@ -48,8 +48,8 @@ class BinImage:
|
||||
if self.magic == b'TRZF':
|
||||
print('TREZOR Firmware Image')
|
||||
total_len = self.vhdrlen + self.hdrlen + self.codelen
|
||||
elif self.magic == b'TRZL':
|
||||
print('TREZOR Loader Image')
|
||||
elif self.magic == b'TRZB':
|
||||
print('TREZOR Bootloader Image')
|
||||
total_len = self.hdrlen + self.codelen
|
||||
else:
|
||||
print('TREZOR Unknown Image')
|
||||
@ -101,10 +101,10 @@ class FirmwareImage(BinImage):
|
||||
f.write(self.serialize_header())
|
||||
f.write(self.code)
|
||||
|
||||
class LoaderImage(BinImage):
|
||||
class BootloaderImage(BinImage):
|
||||
|
||||
def __init__(self, data):
|
||||
super().__init__(data, magic=b'TRZL', max_size=64*1024 + 7*128*1024)
|
||||
super().__init__(data, magic=b'TRZB', max_size=64*1024 + 7*128*1024)
|
||||
|
||||
|
||||
class VendorHeader:
|
||||
@ -188,8 +188,8 @@ class VendorHeader:
|
||||
def binopen(filename):
|
||||
data = open(filename, 'rb').read()
|
||||
magic = data[:4]
|
||||
if magic == b'TRZL':
|
||||
return LoaderImage(data)
|
||||
if magic == b'TRZB':
|
||||
return BootloaderImage(data)
|
||||
if magic == b'TRZV':
|
||||
vheader = VendorHeader(data)
|
||||
if len(data) == vheader.hdrlen:
|
||||
|
Loading…
Reference in New Issue
Block a user