mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-06 14:52:33 +00:00
feat(core): add prepare build for STM32U
5, which sets option bytes so that boardloader starts correctly [no changelog]
This commit is contained in:
parent
e1161866da
commit
175bf3cd8a
@ -11,6 +11,7 @@ MAKE = make -j $(JOBS)
|
|||||||
SCONS = scons -Q -j $(JOBS)
|
SCONS = scons -Q -j $(JOBS)
|
||||||
|
|
||||||
BUILD_DIR = build
|
BUILD_DIR = build
|
||||||
|
PREPARE_BUILD_DIR = $(BUILD_DIR)/prepare
|
||||||
BOARDLOADER_BUILD_DIR = $(BUILD_DIR)/boardloader
|
BOARDLOADER_BUILD_DIR = $(BUILD_DIR)/boardloader
|
||||||
BOOTLOADER_BUILD_DIR = $(BUILD_DIR)/bootloader
|
BOOTLOADER_BUILD_DIR = $(BUILD_DIR)/bootloader
|
||||||
BOOTLOADER_CI_BUILD_DIR = $(BUILD_DIR)/bootloader_ci
|
BOOTLOADER_CI_BUILD_DIR = $(BUILD_DIR)/bootloader_ci
|
||||||
@ -229,6 +230,10 @@ build: build_boardloader build_bootloader build_firmware build_prodtest build_un
|
|||||||
|
|
||||||
build_embed: build_boardloader build_bootloader build_firmware # build boardloader, bootloader, firmware
|
build_embed: build_boardloader build_bootloader build_firmware # build boardloader, bootloader, firmware
|
||||||
|
|
||||||
|
build_prepare: ## build prepare
|
||||||
|
$(SCONS) CFLAGS="$(CFLAGS)" PRODUCTION="$(PRODUCTION)" TREZOR_MODEL="$(TREZOR_MODEL)" \
|
||||||
|
CMAKELISTS="$(CMAKELISTS)" $(PREPARE_BUILD_DIR)/prepare.bin
|
||||||
|
|
||||||
build_boardloader: ## build boardloader
|
build_boardloader: ## build boardloader
|
||||||
$(SCONS) CFLAGS="$(CFLAGS)" PRODUCTION="$(PRODUCTION)" TREZOR_MODEL="$(TREZOR_MODEL)" \
|
$(SCONS) CFLAGS="$(CFLAGS)" PRODUCTION="$(PRODUCTION)" TREZOR_MODEL="$(TREZOR_MODEL)" \
|
||||||
CMAKELISTS="$(CMAKELISTS)" $(BOARDLOADER_BUILD_DIR)/boardloader.bin
|
CMAKELISTS="$(CMAKELISTS)" $(BOARDLOADER_BUILD_DIR)/boardloader.bin
|
||||||
@ -283,9 +288,12 @@ build_cross: ## build mpy-cross port
|
|||||||
|
|
||||||
## clean commands:
|
## clean commands:
|
||||||
|
|
||||||
clean: clean_boardloader clean_bootloader clean_bootloader_emu clean_bootloader_ci clean_prodtest clean_reflash clean_firmware clean_unix clean_cross ## clean all
|
clean: clean_prepare clean_boardloader clean_bootloader clean_bootloader_emu clean_bootloader_ci clean_prodtest clean_reflash clean_firmware clean_unix clean_cross ## clean all
|
||||||
rm -f ".sconsign.dblite"
|
rm -f ".sconsign.dblite"
|
||||||
|
|
||||||
|
clean_prepare: ## clean prepare build
|
||||||
|
rm -rf $(PREPARE_BUILD_DIR)
|
||||||
|
|
||||||
clean_boardloader: ## clean boardloader build
|
clean_boardloader: ## clean boardloader build
|
||||||
rm -rf $(BOARDLOADER_BUILD_DIR)
|
rm -rf $(BOARDLOADER_BUILD_DIR)
|
||||||
|
|
||||||
@ -317,6 +325,9 @@ clean_cross: ## clean mpy-cross build
|
|||||||
|
|
||||||
flash: flash_boardloader flash_bootloader flash_firmware ## flash everything using OpenOCD
|
flash: flash_boardloader flash_bootloader flash_firmware ## flash everything using OpenOCD
|
||||||
|
|
||||||
|
flash_prepare: $(PREPARE_BUILD_DIR)/prepare.bin ## flash prepare using OpenOCD
|
||||||
|
$(OPENOCD) -c "init; reset halt; flash write_image erase $< $(FLASH_START); exit"
|
||||||
|
|
||||||
flash_boardloader: $(BOARDLOADER_BUILD_DIR)/boardloader.bin ## flash boardloader using OpenOCD
|
flash_boardloader: $(BOARDLOADER_BUILD_DIR)/boardloader.bin ## flash boardloader using OpenOCD
|
||||||
$(OPENOCD) -c "init; reset halt; flash write_image erase $< $(BOARDLOADER_START); exit"
|
$(OPENOCD) -c "init; reset halt; flash write_image erase $< $(BOARDLOADER_START); exit"
|
||||||
|
|
||||||
@ -416,6 +427,8 @@ sizecheck: ## check sizes of binary files
|
|||||||
test $(FIRMWARE_P2_MAXSIZE) -ge $(shell wc -c < $(FIRMWARE_BUILD_DIR)/firmware.bin.p2)
|
test $(FIRMWARE_P2_MAXSIZE) -ge $(shell wc -c < $(FIRMWARE_BUILD_DIR)/firmware.bin.p2)
|
||||||
test $(FIRMWARE_MAXSIZE) -ge $(shell wc -c < $(FIRMWARE_BUILD_DIR)/firmware.bin)
|
test $(FIRMWARE_MAXSIZE) -ge $(shell wc -c < $(FIRMWARE_BUILD_DIR)/firmware.bin)
|
||||||
|
|
||||||
|
|
||||||
|
ifeq ($(MCU),$(filter $(MCU),STM32F4))
|
||||||
combine: ## combine boardloader + bootloader + prodtest into one combined image
|
combine: ## combine boardloader + bootloader + prodtest into one combined image
|
||||||
./tools/combine_firmware \
|
./tools/combine_firmware \
|
||||||
$(LAYOUT_FILE) \
|
$(LAYOUT_FILE) \
|
||||||
@ -423,8 +436,6 @@ combine: ## combine boardloader + bootloader + prodtest into one combined image
|
|||||||
-b BOARDLOADER $(BOARDLOADER_BUILD_DIR)/boardloader.bin \
|
-b BOARDLOADER $(BOARDLOADER_BUILD_DIR)/boardloader.bin \
|
||||||
-b BOOTLOADER $(BOOTLOADER_BUILD_DIR)/bootloader.bin \
|
-b BOOTLOADER $(BOOTLOADER_BUILD_DIR)/bootloader.bin \
|
||||||
-b FIRMWARE $(PRODTEST_BUILD_DIR)/prodtest.bin
|
-b FIRMWARE $(PRODTEST_BUILD_DIR)/prodtest.bin
|
||||||
|
|
||||||
ifeq ($(MCU),$(filter $(MCU),STM32F4))
|
|
||||||
combine_fw: ## combine boardloader + bootloader + firmware into one combined image
|
combine_fw: ## combine boardloader + bootloader + firmware into one combined image
|
||||||
./tools/combine_firmware \
|
./tools/combine_firmware \
|
||||||
$(LAYOUT_FILE) \
|
$(LAYOUT_FILE) \
|
||||||
@ -434,10 +445,19 @@ combine_fw: ## combine boardloader + bootloader + firmware into one combined ima
|
|||||||
-b FIRMWARE $(FIRMWARE_BUILD_DIR)/firmware.bin.p1 \
|
-b FIRMWARE $(FIRMWARE_BUILD_DIR)/firmware.bin.p1 \
|
||||||
-b FIRMWARE_P2 $(FIRMWARE_BUILD_DIR)/firmware.bin.p2
|
-b FIRMWARE_P2 $(FIRMWARE_BUILD_DIR)/firmware.bin.p2
|
||||||
else ifeq ($(MCU),$(filter $(MCU),STM32U5))
|
else ifeq ($(MCU),$(filter $(MCU),STM32U5))
|
||||||
|
combine: ## combine boardloader + bootloader + prodtest into one combined image
|
||||||
|
./tools/combine_firmware \
|
||||||
|
$(LAYOUT_FILE) \
|
||||||
|
$(PRODTEST_BUILD_DIR)/combined.bin \
|
||||||
|
-b FLASH $(PREPARE_BUILD_DIR)/prepare.bin \
|
||||||
|
-b BOARDLOADER $(BOARDLOADER_BUILD_DIR)/boardloader.bin \
|
||||||
|
-b BOOTLOADER $(BOOTLOADER_BUILD_DIR)/bootloader.bin \
|
||||||
|
-b FIRMWARE $(PRODTEST_BUILD_DIR)/prodtest.bin
|
||||||
combine_fw: ## combine boardloader + bootloader + firmware into one combined image
|
combine_fw: ## combine boardloader + bootloader + firmware into one combined image
|
||||||
./tools/combine_firmware \
|
./tools/combine_firmware \
|
||||||
$(LAYOUT_FILE) \
|
$(LAYOUT_FILE) \
|
||||||
$(PRODTEST_BUILD_DIR)/combined.bin \
|
$(PRODTEST_BUILD_DIR)/combined.bin \
|
||||||
|
-b FLASH $(PREPARE_BUILD_DIR)/prepare.bin \
|
||||||
-b BOARDLOADER $(BOARDLOADER_BUILD_DIR)/boardloader.bin \
|
-b BOARDLOADER $(BOARDLOADER_BUILD_DIR)/boardloader.bin \
|
||||||
-b BOOTLOADER $(BOOTLOADER_BUILD_DIR)/bootloader.bin \
|
-b BOOTLOADER $(BOOTLOADER_BUILD_DIR)/bootloader.bin \
|
||||||
-b FIRMWARE $(FIRMWARE_BUILD_DIR)/firmware.bin
|
-b FIRMWARE $(FIRMWARE_BUILD_DIR)/firmware.bin
|
||||||
|
144
core/SConscript.prepare
Normal file
144
core/SConscript.prepare
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
# pylint: disable=E0602
|
||||||
|
|
||||||
|
import os
|
||||||
|
import tools
|
||||||
|
|
||||||
|
TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T')
|
||||||
|
CMAKELISTS = int(ARGUMENTS.get('CMAKELISTS', 0))
|
||||||
|
|
||||||
|
if TREZOR_MODEL not in ('T3T1', ):
|
||||||
|
# skip prepare build
|
||||||
|
env = Environment()
|
||||||
|
def build_prepare(target,source,env):
|
||||||
|
print(f'Prepare: nothing to build for Model {TREZOR_MODEL}')
|
||||||
|
program_bin = env.Command(
|
||||||
|
target='prepare.bin',
|
||||||
|
source=None,
|
||||||
|
action=build_prepare
|
||||||
|
)
|
||||||
|
Return()
|
||||||
|
|
||||||
|
FEATURES_WANTED = []
|
||||||
|
|
||||||
|
CCFLAGS_MOD = ''
|
||||||
|
CPPPATH_MOD = []
|
||||||
|
CPPDEFINES_MOD = ["PREPARE"]
|
||||||
|
SOURCE_MOD = []
|
||||||
|
CPPDEFINES_HAL = []
|
||||||
|
SOURCE_HAL = []
|
||||||
|
PATH_HAL = []
|
||||||
|
|
||||||
|
CPPPATH_MOD += [
|
||||||
|
'vendor/trezor-crypto',
|
||||||
|
'vendor/trezor-storage',
|
||||||
|
]
|
||||||
|
|
||||||
|
CCFLAGS_MOD += '-Wno-sequence-point '
|
||||||
|
|
||||||
|
|
||||||
|
env = Environment(ENV=os.environ,
|
||||||
|
CFLAGS='%s -DPRODUCTION=%s' % (ARGUMENTS.get('CFLAGS', ''), ARGUMENTS.get('PRODUCTION', '0')),
|
||||||
|
CONSTRAINTS=[],
|
||||||
|
CPPDEFINES_IMPLICIT=[]
|
||||||
|
)
|
||||||
|
|
||||||
|
FEATURES_AVAILABLE = tools.configure_board(TREZOR_MODEL, FEATURES_WANTED, env, CPPDEFINES_HAL, SOURCE_HAL, PATH_HAL)
|
||||||
|
|
||||||
|
FILE_SUFFIX= env.get('ENV')['SUFFIX']
|
||||||
|
LINKER_SCRIPT_SUFFIX= env.get('ENV')['LINKER_SCRIPT']
|
||||||
|
|
||||||
|
SOURCE_PREPARE = [
|
||||||
|
f"embed/prepare/startup_{FILE_SUFFIX}.s",
|
||||||
|
'embed/prepare/main.c',
|
||||||
|
'embed/lib/terminal.c',
|
||||||
|
'embed/lib/fonts/font_bitmap.c',
|
||||||
|
'embed/lib/mini_printf.c',
|
||||||
|
]
|
||||||
|
|
||||||
|
env.Replace(
|
||||||
|
CP='cp',
|
||||||
|
AS='arm-none-eabi-as',
|
||||||
|
AR='arm-none-eabi-ar',
|
||||||
|
CC='arm-none-eabi-gcc',
|
||||||
|
LINK='arm-none-eabi-gcc',
|
||||||
|
SIZE='arm-none-eabi-size',
|
||||||
|
STRIP='arm-none-eabi-strip',
|
||||||
|
OBJCOPY='arm-none-eabi-objcopy',
|
||||||
|
PYTHON='python',
|
||||||
|
MAKECMAKELISTS='$PYTHON tools/make_cmakelists.py',)
|
||||||
|
|
||||||
|
env.Replace(
|
||||||
|
TREZOR_MODEL=TREZOR_MODEL, )
|
||||||
|
|
||||||
|
env.Replace(
|
||||||
|
COPT=env.get('ENV').get('OPTIMIZE', '-Os'),
|
||||||
|
CCFLAGS='$COPT '
|
||||||
|
'-g3 '
|
||||||
|
'-nostdlib '
|
||||||
|
'-std=gnu11 -Wall -Werror -Wdouble-promotion -Wpointer-arith -Wno-missing-braces -fno-common '
|
||||||
|
'-fsingle-precision-constant -fdata-sections -ffunction-sections '
|
||||||
|
'-ffreestanding '
|
||||||
|
'-fstack-protector-all '
|
||||||
|
+ env.get('ENV')["CPU_CCFLAGS"] + CCFLAGS_MOD,
|
||||||
|
CCFLAGS_QSTR='-DNO_QSTR -DN_X64 -DN_X86 -DN_THUMB',
|
||||||
|
LINKFLAGS=f"-T embed/prepare/memory_{LINKER_SCRIPT_SUFFIX}.ld -Wl,--gc-sections -Wl,-Map=build/prepare/prepare.map -Wl,--warn-common -Wl,--print-memory-usage",
|
||||||
|
CPPPATH=[
|
||||||
|
'embed/prepare',
|
||||||
|
'embed/lib',
|
||||||
|
'embed/models',
|
||||||
|
'embed/trezorhal',
|
||||||
|
'embed/extmod/modtrezorui',
|
||||||
|
'vendor/micropython/lib/cmsis/inc',
|
||||||
|
] + CPPPATH_MOD + PATH_HAL,
|
||||||
|
CPPDEFINES=[
|
||||||
|
'PREPARE',
|
||||||
|
'TREZOR_MODEL_'+TREZOR_MODEL,
|
||||||
|
'USE_HAL_DRIVER',
|
||||||
|
] + CPPDEFINES_MOD + CPPDEFINES_HAL,
|
||||||
|
ASFLAGS=env.get('ENV')['CPU_ASFLAGS'],
|
||||||
|
ASPPFLAGS='$CFLAGS $CCFLAGS',
|
||||||
|
)
|
||||||
|
|
||||||
|
env.Replace(
|
||||||
|
ALLSOURCES=SOURCE_MOD + SOURCE_PREPARE + SOURCE_HAL,
|
||||||
|
ALLDEFS=tools.get_defs_for_cmake(env['CPPDEFINES'] + env['CPPDEFINES_IMPLICIT']))
|
||||||
|
|
||||||
|
cmake_gen = env.Command(
|
||||||
|
target='CMakeLists.txt',
|
||||||
|
source='',
|
||||||
|
action='$MAKECMAKELISTS --sources $ALLSOURCES --dirs $CPPPATH --defs $ALLDEFS',
|
||||||
|
)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Program objects
|
||||||
|
#
|
||||||
|
|
||||||
|
obj_program = []
|
||||||
|
obj_program += env.Object(source=SOURCE_MOD)
|
||||||
|
obj_program += env.Object(source=SOURCE_PREPARE)
|
||||||
|
obj_program += env.Object(source=SOURCE_HAL)
|
||||||
|
|
||||||
|
program_elf = env.Command(
|
||||||
|
target='prepare.elf',
|
||||||
|
source=obj_program,
|
||||||
|
action=
|
||||||
|
'$LINK -o $TARGET $CCFLAGS $CFLAGS $LINKFLAGS $SOURCES -lc_nano -lgcc',
|
||||||
|
)
|
||||||
|
|
||||||
|
BINARY_NAME = f"build/prepare/prepare-{tools.get_model_identifier(TREZOR_MODEL)}"
|
||||||
|
BINARY_NAME += "-" + tools.get_version('embed/prepare/version.h')
|
||||||
|
BINARY_NAME += "-" + tools.get_git_revision_short_hash()
|
||||||
|
BINARY_NAME += "-dirty" if tools.get_git_modified() else ""
|
||||||
|
BINARY_NAME += ".bin"
|
||||||
|
|
||||||
|
if CMAKELISTS != 0:
|
||||||
|
env.Depends(program_elf, cmake_gen)
|
||||||
|
|
||||||
|
program_bin = env.Command(
|
||||||
|
target='prepare.bin',
|
||||||
|
source=program_elf,
|
||||||
|
action=[
|
||||||
|
'$OBJCOPY -O binary -j .vector_table -j .text -j .data -j .rodata -j .capabilities -j .sensitive $SOURCE $TARGET',
|
||||||
|
'$CP $TARGET ' + BINARY_NAME,
|
||||||
|
],
|
||||||
|
)
|
@ -9,5 +9,6 @@ SConscript('SConscript.bootloader_ci', variant_dir='build/bootloader_ci', duplic
|
|||||||
SConscript('SConscript.bootloader_emu', variant_dir='build/bootloader_emu', duplicate=False)
|
SConscript('SConscript.bootloader_emu', variant_dir='build/bootloader_emu', duplicate=False)
|
||||||
SConscript('SConscript.firmware', variant_dir='build/firmware', duplicate=False)
|
SConscript('SConscript.firmware', variant_dir='build/firmware', duplicate=False)
|
||||||
SConscript('SConscript.prodtest', variant_dir='build/prodtest', duplicate=False)
|
SConscript('SConscript.prodtest', variant_dir='build/prodtest', duplicate=False)
|
||||||
|
SConscript('SConscript.prepare', variant_dir='build/prepare', duplicate=False)
|
||||||
SConscript('SConscript.reflash', variant_dir='build/reflash', duplicate=False)
|
SConscript('SConscript.reflash', variant_dir='build/reflash', duplicate=False)
|
||||||
SConscript('SConscript.unix', variant_dir='build/unix', duplicate=False)
|
SConscript('SConscript.unix', variant_dir='build/unix', duplicate=False)
|
||||||
|
34
core/embed/prepare/main.c
Normal file
34
core/embed/prepare/main.c
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Trezor project, https://trezor.io/
|
||||||
|
*
|
||||||
|
* Copyright (c) SatoshiLabs
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include TREZOR_BOARD
|
||||||
|
#include "lowlevel.h"
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
// need the systick timer running before many HAL operations.
|
||||||
|
// want the PVD enabled before flash operations too.
|
||||||
|
periph_init();
|
||||||
|
|
||||||
|
if (sectrue != flash_configure_basic_option_bytes()) {
|
||||||
|
NVIC_SystemReset();
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
109
core/embed/prepare/memory_stm32u58.ld
Normal file
109
core/embed/prepare/memory_stm32u58.ld
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/* Trezor v2 boardloader linker script */
|
||||||
|
|
||||||
|
ENTRY(reset_handler)
|
||||||
|
|
||||||
|
MEMORY {
|
||||||
|
FLASH (rx) : ORIGIN = 0x0C000000, LENGTH = 16K
|
||||||
|
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 192K - 0x100
|
||||||
|
BOOT_ARGS (wal) : ORIGIN = 0x3002FF00, LENGTH = 0x100
|
||||||
|
SRAM2 (wal) : ORIGIN = 0x30030000, LENGTH = 64K
|
||||||
|
SRAM3 (wal) : ORIGIN = 0x30040000, LENGTH = 512K
|
||||||
|
SRAM5 (wal) : ORIGIN = 0x30080000, LENGTH = 0K /* SRAM5 is not available */
|
||||||
|
SRAM6 (wal) : ORIGIN = 0x30080000, LENGTH = 0K /* SRAM6 is not available */
|
||||||
|
SRAM4 (wal) : ORIGIN = 0x38000000, LENGTH = 16K
|
||||||
|
}
|
||||||
|
|
||||||
|
main_stack_base = ORIGIN(SRAM2) + SIZEOF(.stack); /* 8-byte aligned full descending stack */
|
||||||
|
_sstack = ORIGIN(SRAM2);
|
||||||
|
_estack = main_stack_base;
|
||||||
|
|
||||||
|
/* used by the startup code to populate variables used by the C code */
|
||||||
|
data_lma = LOADADDR(.data);
|
||||||
|
data_vma = ADDR(.data);
|
||||||
|
data_size = SIZEOF(.data);
|
||||||
|
|
||||||
|
/* used by the startup code to populate variables used by the C code */
|
||||||
|
sensitive_lma = LOADADDR(.sensitive);
|
||||||
|
sensitive_vma = ADDR(.sensitive);
|
||||||
|
sensitive_size = SIZEOF(.sensitive);
|
||||||
|
|
||||||
|
/* used by the startup code to wipe memory */
|
||||||
|
sram1_start = ORIGIN(SRAM1);
|
||||||
|
sram1_end = ORIGIN(SRAM1) + LENGTH(SRAM1);
|
||||||
|
sram2_start = ORIGIN(SRAM2);
|
||||||
|
sram2_end = ORIGIN(SRAM2) + LENGTH(SRAM2);
|
||||||
|
sram3_start = ORIGIN(SRAM3);
|
||||||
|
sram3_end = ORIGIN(SRAM3) + LENGTH(SRAM3);
|
||||||
|
sram4_start = ORIGIN(SRAM4);
|
||||||
|
sram4_end = ORIGIN(SRAM4) + LENGTH(SRAM4);
|
||||||
|
sram5_start = ORIGIN(SRAM5);
|
||||||
|
sram5_end = ORIGIN(SRAM5) + LENGTH(SRAM5);
|
||||||
|
sram6_start = ORIGIN(SRAM6);
|
||||||
|
sram6_end = ORIGIN(SRAM6) + LENGTH(SRAM6);
|
||||||
|
|
||||||
|
/* reserve 256 bytes for bootloader arguments */
|
||||||
|
boot_args_start = ORIGIN(BOOT_ARGS);
|
||||||
|
boot_args_end = ORIGIN(BOOT_ARGS) + LENGTH(BOOT_ARGS);
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
.vector_table : ALIGN(512) {
|
||||||
|
KEEP(*(.vector_table));
|
||||||
|
} >FLASH AT>FLASH
|
||||||
|
|
||||||
|
.text : ALIGN(4) {
|
||||||
|
*(.text*);
|
||||||
|
. = ALIGN(4); /* make the section size a multiple of the word size */
|
||||||
|
} >FLASH AT>FLASH
|
||||||
|
|
||||||
|
.rodata : ALIGN(4) {
|
||||||
|
*(.rodata*);
|
||||||
|
. = ALIGN(4); /* make the section size a multiple of the word size */
|
||||||
|
} >FLASH AT>FLASH
|
||||||
|
|
||||||
|
.data : ALIGN(4) {
|
||||||
|
*(.data*);
|
||||||
|
. = ALIGN(8);
|
||||||
|
} >SRAM1 AT>FLASH
|
||||||
|
|
||||||
|
/DISCARD/ : {
|
||||||
|
*(.ARM.exidx*);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bss : ALIGN(4) {
|
||||||
|
*(.bss*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >SRAM1
|
||||||
|
|
||||||
|
.buf : ALIGN(4) {
|
||||||
|
*(.buf*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >SRAM1
|
||||||
|
|
||||||
|
.stack : ALIGN(8) {
|
||||||
|
. = 16K; /* Overflow causes UsageFault */
|
||||||
|
} >SRAM2
|
||||||
|
|
||||||
|
.sensitive : ALIGN(8) {
|
||||||
|
*(.sensitive*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >SRAM2 AT>FLASH
|
||||||
|
|
||||||
|
.fb : ALIGN(4) {
|
||||||
|
__fb_start = .;
|
||||||
|
*(.fb1*);
|
||||||
|
*(.fb2*);
|
||||||
|
__fb_end = .;
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >SRAM3
|
||||||
|
|
||||||
|
.boot_args : ALIGN(8) {
|
||||||
|
*(.boot_command*);
|
||||||
|
. = ALIGN(8);
|
||||||
|
*(.boot_args*);
|
||||||
|
. = ALIGN(8);
|
||||||
|
} >BOOT_ARGS
|
||||||
|
|
||||||
|
|
||||||
|
/* Hard-coded address for capabilities structure */
|
||||||
|
.capabilities 0x0C00FF00 : {KEEP(*(.capabilities_section))}
|
||||||
|
}
|
107
core/embed/prepare/startup_stm32u5.s
Normal file
107
core/embed/prepare/startup_stm32u5.s
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
.syntax unified
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
|
.global reset_handler
|
||||||
|
.type reset_handler, STT_FUNC
|
||||||
|
reset_handler:
|
||||||
|
// set the stack protection
|
||||||
|
ldr r0, =_sstack
|
||||||
|
add r0, r0, #16 // padding
|
||||||
|
msr MSPLIM, r0
|
||||||
|
|
||||||
|
bl SystemInit
|
||||||
|
|
||||||
|
// read the first rng data and save it
|
||||||
|
ldr r0, =0 // r0 - previous value
|
||||||
|
ldr r1, =0 // r1 - whether to compare the previous value
|
||||||
|
bl rng_read
|
||||||
|
|
||||||
|
// read the next rng data and make sure it is different than previous
|
||||||
|
// r0 - value returned from previous call
|
||||||
|
ldr r1, =1 // r1 - whether to compare the previous value
|
||||||
|
bl rng_read
|
||||||
|
mov r4, r0 // save TRNG output in r4
|
||||||
|
|
||||||
|
// wipe memory to remove any possible vestiges of sensitive data
|
||||||
|
|
||||||
|
|
||||||
|
fill_ram:
|
||||||
|
ldr r0, =sram1_start // r0 - point to beginning of SRAM
|
||||||
|
ldr r1, =sram1_end // r1 - point to byte after the end of SRAM
|
||||||
|
mov r2, r4 // r2 - the word-sized value to be written
|
||||||
|
bl memset_reg
|
||||||
|
|
||||||
|
ldr r0, =sram2_start // r0 - point to beginning of SRAM
|
||||||
|
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
|
||||||
|
mov r2, r4 // r2 - the word-sized value to be written
|
||||||
|
bl memset_reg
|
||||||
|
|
||||||
|
ldr r0, =sram3_start // r0 - point to beginning of SRAM
|
||||||
|
ldr r1, =sram3_end // r1 - point to byte after the end of SRAM
|
||||||
|
mov r2, r4 // r2 - the word-sized value to be written
|
||||||
|
bl memset_reg
|
||||||
|
|
||||||
|
ldr r0, =sram4_start // r0 - point to beginning of SRAM
|
||||||
|
ldr r1, =sram4_end // r1 - point to byte after the end of SRAM
|
||||||
|
mov r2, r4 // r2 - the word-sized value to be written
|
||||||
|
bl memset_reg
|
||||||
|
|
||||||
|
ldr r0, =sram5_start // r0 - point to beginning of SRAM
|
||||||
|
ldr r1, =sram5_end // r1 - point to byte after the end of SRAM
|
||||||
|
mov r2, r4 // r2 - the word-sized value to be written
|
||||||
|
bl memset_reg
|
||||||
|
|
||||||
|
ldr r0, =sram6_start // r0 - point to beginning of SRAM
|
||||||
|
ldr r1, =sram6_end // r1 - point to byte after the end of SRAM
|
||||||
|
mov r2, r4 // r2 - the word-sized value to be written
|
||||||
|
bl memset_reg
|
||||||
|
|
||||||
|
|
||||||
|
// setup environment for subsequent stage of code
|
||||||
|
|
||||||
|
|
||||||
|
clear_ram:
|
||||||
|
ldr r2, =0 // r2 - the word-sized value to be written
|
||||||
|
ldr r0, =sram1_start // r0 - point to beginning of SRAM
|
||||||
|
ldr r1, =sram1_end // r1 - point to byte after the end of SRAM
|
||||||
|
bl memset_reg
|
||||||
|
ldr r0, =sram2_start // r0 - point to beginning of SRAM
|
||||||
|
ldr r1, =sram2_end // r1 - point to byte after the end of SRAM
|
||||||
|
bl memset_reg
|
||||||
|
ldr r0, =sram3_start // r0 - point to beginning of SRAM
|
||||||
|
ldr r1, =sram3_end // r1 - point to byte after the end of SRAM
|
||||||
|
bl memset_reg
|
||||||
|
ldr r0, =sram4_start // r0 - point to beginning of SRAM
|
||||||
|
ldr r1, =sram4_end // r1 - point to byte after the end of SRAM
|
||||||
|
bl memset_reg
|
||||||
|
ldr r0, =sram5_start // r0 - point to beginning of SRAM
|
||||||
|
ldr r1, =sram5_end // r1 - point to byte after the end of SRAM
|
||||||
|
bl memset_reg
|
||||||
|
ldr r0, =sram6_start // r0 - point to beginning of SRAM
|
||||||
|
ldr r1, =sram6_end // r1 - point to byte after the end of SRAM
|
||||||
|
bl memset_reg
|
||||||
|
|
||||||
|
// copy data in from flash
|
||||||
|
ldr r0, =data_vma // dst addr
|
||||||
|
ldr r1, =data_lma // src addr
|
||||||
|
ldr r2, =data_size // size in bytes
|
||||||
|
bl memcpy
|
||||||
|
|
||||||
|
// copy sensitive data in from flash
|
||||||
|
ldr r0, =sensitive_vma // dst addr
|
||||||
|
ldr r1, =sensitive_lma // src addr
|
||||||
|
ldr r2, =sensitive_size // size in bytes
|
||||||
|
bl memcpy
|
||||||
|
|
||||||
|
// setup the stack protector (see build script "-fstack-protector-all") with an unpredictable value
|
||||||
|
bl rng_get
|
||||||
|
ldr r1, = __stack_chk_guard
|
||||||
|
str r0, [r1]
|
||||||
|
|
||||||
|
// enter the application code
|
||||||
|
bl main
|
||||||
|
|
||||||
|
b shutdown_privileged
|
||||||
|
|
||||||
|
.end
|
4
core/embed/prepare/version.h
Normal file
4
core/embed/prepare/version.h
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#define VERSION_MAJOR 0
|
||||||
|
#define VERSION_MINOR 0
|
||||||
|
#define VERSION_PATCH 1
|
||||||
|
#define VERSION_BUILD 0
|
@ -26,6 +26,7 @@ secbool flash_check_option_bytes(void);
|
|||||||
void flash_lock_option_bytes(void);
|
void flash_lock_option_bytes(void);
|
||||||
void flash_unlock_option_bytes(void);
|
void flash_unlock_option_bytes(void);
|
||||||
uint32_t flash_set_option_bytes(void);
|
uint32_t flash_set_option_bytes(void);
|
||||||
|
secbool flash_configure_basic_option_bytes(void);
|
||||||
secbool flash_configure_option_bytes(void);
|
secbool flash_configure_option_bytes(void);
|
||||||
void periph_init(void);
|
void periph_init(void);
|
||||||
secbool reset_flags_check(void);
|
secbool reset_flags_check(void);
|
||||||
|
@ -170,6 +170,18 @@ secbool flash_check_option_bytes(void) {
|
|||||||
return sectrue;
|
return sectrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
secbool flash_check_basic_option_bytes(void) {
|
||||||
|
flash_wait_and_clear_status_flags();
|
||||||
|
|
||||||
|
if ((FLASH->OPTR & FLASH_OPTR_TZEN) == 0) {
|
||||||
|
return secfalse;
|
||||||
|
}
|
||||||
|
if (FLASH->SECBOOTADD0R != FALSH_SECBOOTADD0R_VALUE) {
|
||||||
|
return secfalse;
|
||||||
|
}
|
||||||
|
return sectrue;
|
||||||
|
}
|
||||||
|
|
||||||
void flash_lock_option_bytes(void) {
|
void flash_lock_option_bytes(void) {
|
||||||
FLASH->NSCR |= FLASH_NSCR_OPTLOCK; // lock the option bytes
|
FLASH->NSCR |= FLASH_NSCR_OPTLOCK; // lock the option bytes
|
||||||
}
|
}
|
||||||
@ -186,6 +198,37 @@ void flash_unlock_option_bytes(void) {
|
|||||||
; // wait until the flash option control register is unlocked
|
; // wait until the flash option control register is unlocked
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t flash_set_basic_option_bytes(void) {
|
||||||
|
if (flash_unlock_write() != sectrue) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
flash_wait_and_clear_status_flags();
|
||||||
|
flash_unlock_option_bytes();
|
||||||
|
flash_wait_and_clear_status_flags();
|
||||||
|
|
||||||
|
FLASH->OPTR |= FLASH_OPTR_TZEN;
|
||||||
|
|
||||||
|
FLASH->SECBOOTADD0R = FALSH_SECBOOTADD0R_VALUE;
|
||||||
|
|
||||||
|
FLASH_WaitForLastOperation(HAL_MAX_DELAY);
|
||||||
|
|
||||||
|
FLASH->NSCR |= FLASH_NSCR_OPTSTRT;
|
||||||
|
uint32_t result =
|
||||||
|
flash_wait_and_clear_status_flags(); // wait until changes are committed
|
||||||
|
|
||||||
|
FLASH_WaitForLastOperation(HAL_MAX_DELAY);
|
||||||
|
|
||||||
|
FLASH->NSCR |= FLASH_NSCR_OBL_LAUNCH; // begin committing changes to flash
|
||||||
|
result =
|
||||||
|
flash_wait_and_clear_status_flags(); // wait until changes are committed
|
||||||
|
flash_lock_option_bytes();
|
||||||
|
|
||||||
|
if (flash_lock_write() != sectrue) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t flash_set_option_bytes(void) {
|
uint32_t flash_set_option_bytes(void) {
|
||||||
if (flash_unlock_write() != sectrue) {
|
if (flash_unlock_write() != sectrue) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -239,6 +282,18 @@ void check_oem_keys(void) {
|
|||||||
ensure(((FLASH->NSSR & FLASH_NSSR_OEM2LOCK) == 0) * sectrue, "OEM2 KEY SET");
|
ensure(((FLASH->NSSR & FLASH_NSSR_OEM2LOCK) == 0) * sectrue, "OEM2 KEY SET");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
secbool flash_configure_basic_option_bytes(void) {
|
||||||
|
if (sectrue == flash_check_basic_option_bytes()) {
|
||||||
|
return sectrue; // we DID NOT have to change the option bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
flash_set_basic_option_bytes();
|
||||||
|
|
||||||
|
} while (sectrue != flash_check_basic_option_bytes());
|
||||||
|
return secfalse; // notify that we DID have to change the option bytes
|
||||||
|
}
|
||||||
|
|
||||||
secbool flash_configure_option_bytes(void) {
|
secbool flash_configure_option_bytes(void) {
|
||||||
if (sectrue == flash_check_option_bytes()) {
|
if (sectrue == flash_check_option_bytes()) {
|
||||||
return sectrue; // we DID NOT have to change the option bytes
|
return sectrue; // we DID NOT have to change the option bytes
|
||||||
|
Loading…
Reference in New Issue
Block a user