chore(core): refactor boot_args

[no changelog]
pull/3474/head
cepetr 7 months ago committed by TychoVrahe
parent 353095ae95
commit c4c571d837

@ -127,6 +127,7 @@ SOURCE_BOOTLOADER = [
]
SOURCE_TREZORHAL = [
'embed/trezorhal/unix/boot_args.c',
'embed/trezorhal/unix/display-unix.c',
'embed/trezorhal/unix/flash.c',
'embed/trezorhal/unix/common.c',

@ -378,6 +378,7 @@ SOURCE_MICROPYTHON = [
]
SOURCE_UNIX = [
'embed/trezorhal/unix/boot_args.c',
'embed/trezorhal/unix/translations.c',
'embed/trezorhal/unix/common.c',
'embed/trezorhal/unix/display-unix.c',

@ -297,7 +297,7 @@ int main(void) {
mpu_config_off();
// g_boot_flag is preserved on STM32U5
// g_boot_command is preserved on STM32U5
jump_to(BOOTLOADER_START + IMAGE_HEADER_SIZE);
return 0;

@ -4,8 +4,8 @@ ENTRY(reset_handler)
MEMORY {
FLASH (rx) : ORIGIN = 0x0C004000, LENGTH = 48K
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 768K - (0x100 + 4)
BOOT_ARGS (wal) : ORIGIN = 0x300BFEFC, LENGTH = (0x100 + 4)
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 768K - 0x100
BOOT_ARGS (wal) : ORIGIN = 0x300BFF00, LENGTH = 0x100
SRAM2 (wal) : ORIGIN = 0x300C0000, LENGTH = 64K
SRAM3 (wal) : ORIGIN = 0x300D0000, LENGTH = 832K
SRAM5 (wal) : ORIGIN = 0x301A0000, LENGTH = 832K
@ -44,8 +44,6 @@ 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);
g_boot_args = (boot_args_start + 4);
g_boot_flag = boot_args_start;
SECTIONS {
.vector_table : ALIGN(512) {
@ -104,6 +102,14 @@ SECTIONS {
. = ALIGN(4);
} >SRAM5
.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))}
}

@ -1,19 +0,0 @@
#ifndef BOOT_INTERNAL_H
#define BOOT_INTERNAL_H
#include <boot_args.h>
#include <stdint.h>
// The 'g_boot_command' variable stores the 'command' passed to the
// function 'svc_reboot_to_bootloader()'. It may be one of the
// 'BOOT_COMMAND_xxx' values defined in the enumeration, or it could
// be any other value that should be treated as a non-special action,
// in which case the bootloader should behave as if the device was
// just powered up. The variable is set before the main() is called.
extern boot_command_t g_boot_command;
// The 'g_boot_args' array stores extra arguments passed
// function 'svc_reboot_to_bootloader()'
extern uint8_t g_boot_args[BOOT_ARGS_SIZE];
#endif // BOOT_INTERNAL_H

@ -2,7 +2,7 @@
#include <unistd.h>
#include TREZOR_BOARD
#include "boot_internal.h"
#include "boot_args.h"
#include "bootui.h"
#include "common.h"
#include "display.h"
@ -19,11 +19,6 @@
uint8_t *FIRMWARE_START = 0;
// Simulation of a boot command normally grabbed during reset processing
boot_command_t g_boot_command = BOOT_COMMAND_NONE;
// Simulation of a boot args normally sitting at the BOOT_ARGS region
uint8_t g_boot_args[BOOT_ARGS_SIZE];
void set_core_clock(int) {}
int bootloader_main(void);
@ -55,7 +50,7 @@ void usage(void) {
printf(" -h show this help\n");
}
bool load_firmware(const char *filename) {
bool load_firmware(const char *filename, uint8_t *hash) {
// read the first 6 kB of firmware file into a buffer
FILE *file = fopen(filename, "rb");
if (!file) {
@ -87,7 +82,8 @@ bool load_firmware(const char *filename) {
BLAKE2S_CTX ctx;
blake2s_Init(&ctx, BLAKE2S_DIGEST_LENGTH);
blake2s_Update(&ctx, buffer, vhdr.hdrlen + hdr->hdrlen);
blake2s_Final(&ctx, g_boot_args, BLAKE2S_DIGEST_LENGTH);
blake2s_Final(&ctx, hash, BLAKE2S_DIGEST_LENGTH);
return true;
}
@ -131,7 +127,7 @@ __attribute__((noreturn)) int main(int argc, char **argv) {
while ((opt = getopt(argc, argv, "hslec:b:f:")) != -1) {
switch (opt) {
case 's':
g_boot_command = BOOT_COMMAND_STOP_AND_WAIT;
bootargs_set(BOOT_COMMAND_STOP_AND_WAIT, NULL, 0);
break;
case 'e':
display_error = true;
@ -145,10 +141,11 @@ __attribute__((noreturn)) int main(int argc, char **argv) {
bitcoin_only = atoi(optarg);
break;
case 'f':
g_boot_command = BOOT_COMMAND_INSTALL_UPGRADE;
if (!load_firmware(optarg)) {
uint8_t hash[BLAKE2S_DIGEST_LENGTH];
if (!load_firmware(optarg, hash)) {
exit(1);
}
bootargs_set(BOOT_COMMAND_INSTALL_UPGRADE, hash, sizeof(hash));
break;
#ifdef USE_OPTIGA
case 'l':

@ -20,7 +20,7 @@
#include <string.h>
#include <sys/types.h>
#include "boot_internal.h"
#include "boot_args.h"
#include "common.h"
#include "display.h"
#include "display_utils.h"
@ -513,7 +513,7 @@ int bootloader_main(void) {
check_bootloader_version();
#endif
switch (g_boot_command) {
switch (bootargs_get_command()) {
case BOOT_COMMAND_STOP_AND_WAIT:
// firmare requested to stay in bootloader
stay_in_bootloader = sectrue;

@ -29,7 +29,6 @@ sram_end = ORIGIN(SRAM) + LENGTH(SRAM);
/* reserve 256 bytes for bootloader arguments */
boot_args_start = ORIGIN(BOOT_ARGS);
boot_args_end = ORIGIN(BOOT_ARGS) + LENGTH(BOOT_ARGS);
g_boot_args = boot_args_start;
_codelen = SIZEOF(.flash) + SIZEOF(.data);
@ -70,4 +69,9 @@ SECTIONS {
. = ALIGN(4);
} >SRAM
.boot_args : ALIGN(8) {
*(.boot_args*);
. = ALIGN(8);
} >BOOT_ARGS
}

@ -4,8 +4,8 @@ ENTRY(reset_handler)
MEMORY {
FLASH (rx) : ORIGIN = 0x0C010000, LENGTH = 128K
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 768K - (0x100 + 4)
BOOT_ARGS (wal) : ORIGIN = 0x300BFEFC, LENGTH = (0x100 + 4)
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 768K - 0x100
BOOT_ARGS (wal) : ORIGIN = 0x300BFF00, LENGTH = 0x100
SRAM2 (wal) : ORIGIN = 0x300C0000, LENGTH = 64K
SRAM3 (wal) : ORIGIN = 0x300D0000, LENGTH = 832K
SRAM5 (wal) : ORIGIN = 0x301A0000, LENGTH = 832K
@ -44,8 +44,6 @@ 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);
g_boot_args = (boot_args_start + 4);
g_boot_flag = boot_args_start;
_codelen = SIZEOF(.flash) + SIZEOF(.data) + SIZEOF(.sensitive);
@ -104,4 +102,11 @@ SECTIONS {
__fb_end = .;
. = ALIGN(4);
} >SRAM5
.boot_args : ALIGN(8) {
*(.boot_command*);
. = ALIGN(8);
*(.boot_args*);
. = ALIGN(8);
} >BOOT_ARGS
}

@ -24,7 +24,7 @@
#include <pb_encode.h>
#include "messages.pb.h"
#include "boot_internal.h"
#include "boot_args.h"
#include "common.h"
#include "flash.h"
#include "image.h"
@ -598,7 +598,7 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size,
secbool is_ilu = secfalse; // interaction-less update
if (g_boot_command == BOOT_COMMAND_INSTALL_UPGRADE) {
if (bootargs_get_command() == BOOT_COMMAND_INSTALL_UPGRADE) {
BLAKE2S_CTX ctx;
uint8_t hash[BLAKE2S_DIGEST_LENGTH];
blake2s_Init(&ctx, BLAKE2S_DIGEST_LENGTH);
@ -607,7 +607,7 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size,
blake2s_Final(&ctx, hash, BLAKE2S_DIGEST_LENGTH);
// the firmware must be the same as confirmed by the user
if (memcmp(&g_boot_args[0], hash, sizeof(hash)) != 0) {
if (memcmp(bootargs_get_args()->hash, hash, sizeof(hash)) != 0) {
MSG_SEND_INIT(Failure);
MSG_SEND_ASSIGN_VALUE(code, FailureType_Failure_ProcessError);
MSG_SEND_ASSIGN_STRING(message, "Firmware mismatch");

@ -33,9 +33,9 @@ reset_handler:
// subsequent operations, it is not necessary to insert a memory barrier instruction."
cpsie f
// r11 contains argument passed to reboot_to_bootloader()
// r11 contains the command passed to bootargs_set()
// function called when the firmware rebooted to the bootloader
ldr r0, =g_boot_command
ldr r0, =g_boot_command_shadow
str r11, [r0]
// enter the application code
@ -43,12 +43,5 @@ reset_handler:
b shutdown_privileged
.bss
.global g_boot_command
g_boot_command:
.word 0
.end

@ -49,12 +49,12 @@ reset_handler:
ldr r1, = __stack_chk_guard
str r0, [r1]
//
ldr r0, =g_boot_flag
ldr r1, [r0]
// copy & clear g_boot_command
ldr r0, =g_boot_command
ldr r1, [r0]
ldr r0, =g_boot_command_shadow
str r1, [r0]
ldr r0, =g_boot_flag
ldr r0, =g_boot_command
mov r1, #0
str r1, [r0]
@ -69,10 +69,4 @@ reset_handler:
b shutdown_privileged
.bss
.global g_boot_command
g_boot_command:
.word 0
.end

@ -69,4 +69,8 @@ SECTIONS {
. = ALIGN(4);
} >SRAM
.boot_args : ALIGN(8) {
*(.boot_args*);
. = ALIGN(8);
} >BOOT_ARGS
}

@ -4,8 +4,8 @@ ENTRY(reset_handler)
MEMORY {
FLASH (rx) : ORIGIN = 0x0C010000, LENGTH = 128K
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 768K - (0x100 + 4)
BOOT_ARGS (wal) : ORIGIN = 0x300BFEFC, LENGTH = (0x100 + 4)
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 768K - 0x100
BOOT_ARGS (wal) : ORIGIN = 0x300BFF00, LENGTH = 0x100
SRAM2 (wal) : ORIGIN = 0x300C0000, LENGTH = 64K
SRAM3 (wal) : ORIGIN = 0x300D0000, LENGTH = 832K
SRAM5 (wal) : ORIGIN = 0x301A0000, LENGTH = 832K
@ -44,8 +44,6 @@ 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);
g_boot_args = (boot_args_start + 4);
g_boot_flag = boot_args_start;
_codelen = SIZEOF(.flash) + SIZEOF(.data) + SIZEOF(.sensitive);
@ -104,4 +102,11 @@ SECTIONS {
__fb_end = .;
. = ALIGN(4);
} >SRAM5
.boot_args : ALIGN(8) {
*(.boot_command*);
. = ALIGN(8);
*(.boot_args*);
. = ALIGN(8);
} >BOOT_ARGS
}

@ -49,15 +49,6 @@ reset_handler:
ldr r1, = __stack_chk_guard
str r0, [r1]
//
ldr r0, =g_boot_flag
ldr r1, [r0]
ldr r0, =g_boot_command
str r1, [r0]
ldr r0, =g_boot_flag
mov r1, #0
str r1, [r0]
// re-enable exceptions
// according to "ARM Cortex-M Programming Guide to Memory Barrier Instructions" Application Note 321, section 4.7:
// "If it is not necessary to ensure that a pended interrupt is recognized immediately before
@ -69,10 +60,4 @@ reset_handler:
b shutdown_privileged
.bss
.global g_boot_command
g_boot_command:
.word 0
.end

@ -286,7 +286,8 @@ STATIC mp_obj_t mod_trezorutils_reboot_to_bootloader(size_t n_args,
mp_get_buffer_raise(args[1], &boot_args, MP_BUFFER_READ);
}
svc_reboot_to_bootloader(boot_command, boot_args.buf, boot_args.len);
bootargs_set(boot_command, boot_args.buf, boot_args.len);
svc_reboot_to_bootloader();
#endif
return mp_const_none;
}

@ -4,8 +4,8 @@ ENTRY(reset_handler)
MEMORY {
FLASH (rx) : ORIGIN = 0x0C050000, LENGTH = 3648K
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 768K - (0x100 + 4)
BOOT_ARGS (wal) : ORIGIN = 0x300BFEFC, LENGTH = (0x100 + 4)
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 768K - 0x100
BOOT_ARGS (wal) : ORIGIN = 0x300BFF00, LENGTH = 0x100
SRAM2 (wal) : ORIGIN = 0x300C0000, LENGTH = 64K
SRAM3 (wal) : ORIGIN = 0x300D0000, LENGTH = 832K
SRAM5 (wal) : ORIGIN = 0x301A0000, LENGTH = 832K
@ -44,8 +44,6 @@ 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);
g_boot_args = (boot_args_start + 4);
g_boot_flag = boot_args_start;
_codelen = SIZEOF(.flash) + SIZEOF(.data) + SIZEOF(.sensitive);
_flash_start = ORIGIN(FLASH);
@ -120,4 +118,11 @@ SECTIONS {
__fb_end = .;
. = ALIGN(4);
} >SRAM5
.boot_args : ALIGN(8) {
*(.boot_command*);
. = ALIGN(8);
*(.boot_args*);
. = ALIGN(8);
} >BOOT_ARGS
}

@ -26,7 +26,6 @@ ccmram_end = ORIGIN(CCMRAM) + LENGTH(CCMRAM);
/* reserve 256 bytes for bootloader arguments */
boot_args_start = ORIGIN(BOOT_ARGS);
boot_args_end = ORIGIN(BOOT_ARGS) + LENGTH(BOOT_ARGS);
g_boot_args = boot_args_start;
/* used by the startup code to wipe memory */
sram_start = ORIGIN(SRAM);
@ -97,4 +96,9 @@ SECTIONS {
*(.no_dma_buffers*);
. = ALIGN(4);
} >CCMRAM
.boot_args : ALIGN(8) {
*(.boot_args*);
. = ALIGN(8);
} >BOOT_ARGS
}

@ -74,4 +74,9 @@ SECTIONS {
.stack : ALIGN(8) {
. = 4K; /* this acts as a build time assertion that at least this much memory is available for stack use */
} >SRAM
.boot_args : ALIGN(8) {
*(.boot_args*);
. = ALIGN(8);
} >BOOT_ARGS
}

@ -4,8 +4,8 @@ ENTRY(reset_handler)
MEMORY {
FLASH (rx) : ORIGIN = 0x0C050000, LENGTH = 3648K
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 768K - (0x100 + 4)
BOOT_ARGS (wal) : ORIGIN = 0x300BFEFC, LENGTH = (0x100 + 4)
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 768K - 0x100
BOOT_ARGS (wal) : ORIGIN = 0x300BFF00, LENGTH = 0x100
SRAM2 (wal) : ORIGIN = 0x300C0000, LENGTH = 64K
SRAM3 (wal) : ORIGIN = 0x300D0000, LENGTH = 832K
SRAM5 (wal) : ORIGIN = 0x301A0000, LENGTH = 832K
@ -44,9 +44,6 @@ 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);
g_boot_args = (boot_args_start + 4);
g_boot_flag= boot_args_start;
_codelen = SIZEOF(.flash) + SIZEOF(.data) + SIZEOF(.sensitive);
_flash_start = ORIGIN(FLASH);
_flash_end = ORIGIN(FLASH) + LENGTH(FLASH);
@ -120,4 +117,11 @@ SECTIONS {
__fb_end = .;
. = ALIGN(4);
} >SRAM5
.boot_args : ALIGN(8) {
*(.boot_command*);
. = ALIGN(8);
*(.boot_args*);
. = ALIGN(8);
} >BOOT_ARGS
}

@ -73,4 +73,9 @@ SECTIONS {
.stack : ALIGN(8) {
. = 4K; /* this acts as a build time assertion that at least this much memory is available for stack use */
} >SRAM
.boot_args : ALIGN(8) {
*(.boot_args*);
. = ALIGN(8);
} >BOOT_ARGS
}

@ -4,8 +4,8 @@ ENTRY(reset_handler)
MEMORY {
FLASH (rx) : ORIGIN = 0x0C050000, LENGTH = 3648K
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 768K - (0x100 + 4)
BOOT_ARGS (wal) : ORIGIN = 0x300BFEFC, LENGTH = (0x100 + 4)
SRAM1 (wal) : ORIGIN = 0x30000000, LENGTH = 768K - 0x100
BOOT_ARGS (wal) : ORIGIN = 0x300BFF00, LENGTH = 0x100
SRAM2 (wal) : ORIGIN = 0x300C0000, LENGTH = 64K
SRAM3 (wal) : ORIGIN = 0x300D0000, LENGTH = 832K
SRAM5 (wal) : ORIGIN = 0x301A0000, LENGTH = 832K
@ -44,8 +44,6 @@ 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);
g_boot_args = (boot_args_start + 4);
g_boot_flag = boot_args_start;
_codelen = SIZEOF(.flash) + SIZEOF(.data) + SIZEOF(.sensitive);
_flash_start = ORIGIN(FLASH);
@ -120,4 +118,11 @@ SECTIONS {
__fb_end = .;
. = ALIGN(4);
} >SRAM5
.boot_args : ALIGN(8) {
*(.boot_command*);
. = ALIGN(8);
*(.boot_args*);
. = ALIGN(8);
} >BOOT_ARGS
}

@ -1,6 +1,9 @@
#ifndef TREZORHAL_BOOT_ARGS_H
#define TREZORHAL_BOOT_ARGS_H
#include <stddef.h>
#include <stdint.h>
// Defines boot command for 'svc_reboot_to_bootloader()' function
typedef enum {
// Normal boot sequence
@ -11,8 +14,26 @@ typedef enum {
BOOT_COMMAND_INSTALL_UPGRADE = 0xFA4A5C8D,
} boot_command_t;
// Maximum size of extra arguments passed to
// 'svc_reboot_to_bootloader()' function
#define BOOT_ARGS_SIZE 256
// Maximum size boot_args array
#define BOOT_ARGS_MAX_SIZE (256 - 8)
typedef union {
uint8_t raw[BOOT_ARGS_MAX_SIZE];
// firmware header hash, BOOT_COMMAND_INSTALL_UPGRADE
uint8_t hash[32];
} boot_args_t;
// Sets boot command and arguments for the next reboot
// arguments have too respect boot_args_t structure layout
// (function can be called multiple times before reboting)
void bootargs_set(boot_command_t command, const void* args, size_t args_size);
// Returns the last boot command set by bootargs_set_command()
boot_command_t bootargs_get_command();
// Returns the pointer to boot arguments
const boot_args_t* bootargs_get_args();
#endif // TREZORHAL_BOOT_ARGS_H

@ -0,0 +1,44 @@
#include "../boot_args.h"
#include <common.h>
#include <string.h>
// The 'g_boot_command_shadow' shadows a real boot command passed
// to the bootloader.
// 1. In the bootloader, its value is set in the startup code.
// 2. In the firmware it holds command for the next boot and it is used
// when svc_reboot_to_bootloader() is called
boot_command_t g_boot_command_shadow;
#ifdef STM32U5
// The 'g_boot_command' is persistent variable that holds the 'command'
// for the next reboot/jump to the bootloader. Its value is set to
// g_boot_command_shadow when 'svc_reboot_to_bootloader()' is called.
boot_command_t __attribute__((section(".boot_command"))) g_boot_command;
#endif
// The 'g_boot_args' is persistent array that stores extra arguments passed
// to the function bootargs_set.
static boot_args_t __attribute__((section(".boot_args"))) g_boot_args;
void bootargs_set(boot_command_t command, const void* args, size_t args_size) {
// save boot command
g_boot_command_shadow = command;
size_t copy_size = 0;
// copy arguments up to BOOT_ARGS_MAX_SIZE
if (args != NULL && args_size > 0) {
copy_size = MIN(args_size, BOOT_ARGS_MAX_SIZE);
memcpy(&g_boot_args.raw[0], args, copy_size);
}
// clear rest of boot_args array
size_t clear_size = BOOT_ARGS_MAX_SIZE - copy_size;
if (clear_size > 0) {
memset(&g_boot_args.raw[copy_size], 0, clear_size);
}
}
boot_command_t bootargs_get_command() { return g_boot_command_shadow; }
const boot_args_t* bootargs_get_args() { return &g_boot_args; }

@ -8,31 +8,11 @@
#ifdef ARM_USER_MODE
// Saves extra parameters for the bootloader
static void _copy_boot_args(const void *args, size_t args_size) {
// symbols imported from the linker script
extern uint8_t g_boot_args;
extern uint8_t boot_args_end;
uint8_t *p = &g_boot_args;
if (args != NULL && args_size > 0) {
size_t max_size = &boot_args_end - &g_boot_args;
size_t copy_size = MIN(args_size, max_size);
memcpy(p, args, copy_size);
p += args_size;
}
if (p < &boot_args_end) {
memset(p, 0, &boot_args_end - p);
}
}
#ifdef STM32U5
extern uint32_t g_boot_flag;
extern uint32_t g_boot_command;
__attribute__((noreturn)) static void _reboot_to_bootloader(
boot_command_t boot_command) {
g_boot_flag = boot_command;
g_boot_command = boot_command;
__disable_irq();
delete_secrets();
NVIC_SystemReset();
@ -47,9 +27,8 @@ __attribute__((noreturn)) static void _reboot_to_bootloader(
}
#endif
void svc_reboot_to_bootloader(boot_command_t boot_command, const void *args,
size_t args_size) {
_copy_boot_args(args, args_size);
void svc_reboot_to_bootloader(void) {
boot_command_t boot_command = bootargs_get_command();
if (is_mode_unprivileged() && !is_mode_handler()) {
register uint32_t r0 __asm__("r0") = boot_command;
__asm__ __volatile__("svc %0" ::"i"(SVC_REBOOT_TO_BOOTLOADER), "r"(r0)

@ -68,8 +68,7 @@ static inline void svc_shutdown(void) {
}
}
void svc_reboot_to_bootloader(boot_command_t boot_command, const void* args,
size_t args_size);
void svc_reboot_to_bootloader(void);
static inline uint32_t svc_get_systick_val(void) {
if (is_mode_unprivileged() && !is_mode_handler()) {

@ -0,0 +1,44 @@
#include "../boot_args.h"
#include <common.h>
#include <string.h>
// The 'g_boot_command_shadow' variable stores the 'command' for the next
// reboot/jumping to the bootloadeer. It may be one of the
// 'BOOT_COMMAND_xxx' values defined in the enumeration, or it could
// be any other value that should be treated as a non-special action,
// in which case the bootloader should behave as if the device was
// just powered up.
static boot_command_t g_boot_command_shadow;
// The 'g_boot_args' array stores extra arguments passed
// function boot_args. It sits at section that persists jump to the bootloader.
static boot_args_t g_boot_args;
void bootargs_set(boot_command_t command, const void* args, size_t args_size) {
// save boot command
g_boot_command_shadow = command;
size_t copy_size = 0;
// copy arguments up to BOOT_ARGS_MAX_SIZE
if (args != NULL && args_size > 0) {
copy_size = MIN(args_size, BOOT_ARGS_MAX_SIZE);
memcpy(&g_boot_args.raw[0], args, copy_size);
}
// clear rest of boot_args array
size_t clear_size = BOOT_ARGS_MAX_SIZE - copy_size;
if (clear_size > 0) {
memset(&g_boot_args.raw[copy_size], 0, clear_size);
}
}
void bootargs_clear() {
g_boot_command_shadow = BOOT_COMMAND_NONE;
memset(&g_boot_args, 0, sizeof(g_boot_args));
}
boot_command_t bootargs_get_command() { return g_boot_command_shadow; }
const boot_args_t* bootargs_get_args() { return &g_boot_args; }

@ -40,6 +40,7 @@ def stm32f4_common_files(env, defines, sources, paths):
sources += [
"embed/trezorhal/stm32f4/board_capabilities.c",
"embed/trezorhal/stm32f4/boot_args.c",
"embed/trezorhal/stm32f4/common.c",
"embed/trezorhal/stm32f4/fault_handlers.c",
"embed/trezorhal/stm32f4/flash.c",

@ -49,6 +49,7 @@ def stm32u5_common_files(env, defines, sources, paths):
sources += [
"embed/trezorhal/stm32u5/board_capabilities.c",
"embed/trezorhal/stm32u5/boot_args.c",
"embed/trezorhal/stm32u5/common.c",
"embed/trezorhal/stm32u5/fault_handlers.c",
"embed/trezorhal/stm32u5/flash.c",

Loading…
Cancel
Save