rename loader to bootloader

pull/25/head
Pavol Rusnak 7 years ago
parent 0633506166
commit 0c060b6d4a
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D

@ -20,7 +20,7 @@ script:
- make build_boardloader
- make build_loader
- make build_bootloader
- make build_firmware

@ -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

@ -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…
Cancel
Save