mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-19 05:58:09 +00:00
chore(core): refactor boot_args
[no changelog]
This commit is contained in:
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
|
||||
|
44
core/embed/trezorhal/stm32f4/boot_args.c
Normal file
44
core/embed/trezorhal/stm32f4/boot_args.c
Normal file
@ -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()) {
|
||||
|
1
core/embed/trezorhal/stm32u5/boot_args.c
Symbolic link
1
core/embed/trezorhal/stm32u5/boot_args.c
Symbolic link
@ -0,0 +1 @@
|
||||
../stm32f4/boot_args.c
|
44
core/embed/trezorhal/unix/boot_args.c
Normal file
44
core/embed/trezorhal/unix/boot_args.c
Normal file
@ -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…
Reference in New Issue
Block a user