Skip to content

bootloader-fw-link: Use RAM to communicate #1423

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bootloader.ld
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ SECTIONS
{
. = ALIGN(4);
_srtt = .;
*(.auto_enter);
*(.segger_rtt);
*(.segger_rtt_buf);
_ertt = .;
Expand Down
1 change: 1 addition & 0 deletions firmware.ld
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ SECTIONS
{
. = ALIGN(4);
_srtt = .;
*(.auto_enter);
*(.segger_rtt);
*(.segger_rtt_buf);
_ertt = .;
Expand Down
12 changes: 5 additions & 7 deletions src/bootloader/bootloader.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@

#include <assert.h>

// Section is fixed in ram, so can be used to communicate between fw/bl
volatile secbool_u32 auto_enter __attribute__((section(".auto_enter")));

#define BOOT_OP_LEN 2u // 1 byte op code and 1 byte parameter
#define BOOTLOADER_CMD (HID_VENDOR_FIRST + 0x03) // Hardware wallet command

Expand Down Expand Up @@ -758,12 +761,7 @@ static size_t _api_versions(uint8_t* output)

static void _api_reboot(void)
{
chunk_shared_t shared_data;
memory_read_shared_bootdata(&shared_data);
if (shared_data.fields.auto_enter == sectrue_u8) {
shared_data.fields.auto_enter = secfalse_u8;
_write_chunk(FLASH_SHARED_DATA_START, shared_data.bytes);
}
auto_enter = secfalse_u32;
_reset_mcu();
}

Expand Down Expand Up @@ -977,7 +975,7 @@ void bootloader_jump(void)

UG_FontSelect(&font_font_a_9X9);

if (shared_data.fields.auto_enter != sectrue_u8) {
if (auto_enter != sectrue_u32) {
#ifdef BOOTLOADER_DEVDEVICE
if (!_devdevice_enter(_firmware_verified_jump(&bootdata, secfalse_u32))) {
_binary_exec();
Expand Down
8 changes: 4 additions & 4 deletions src/common_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,18 +73,18 @@ void common_main(void)
mpu_bitbox02_init();
if (!memory_setup(&_memory_interface_functions)) {
// If memory setup failed, this also might fail, but can't hurt to try.
AbortAutoenter("memory_setup failed");
Abort("memory_setup failed");
}

if (!_setup_wally()) {
AbortAutoenter("_setup_wally failed");
Abort("_setup_wally failed");
}

/* Enable/configure SmartEEPROM. */
smarteeprom_bb02_config();

if (!securechip_init()) {
AbortAutoenter("Failed to detect securechip");
Abort("Failed to detect securechip");
}
// securechip_setup must come after memory_setup, so the io/auth keys to be
// used are already initialized.
Expand All @@ -96,6 +96,6 @@ void common_main(void)
sizeof(errmsg),
"Securechip setup failed.\nError code: %i\nPlease contact support.",
securechip_result);
AbortAutoenter(errmsg);
Abort(errmsg);
}
}
16 changes: 3 additions & 13 deletions src/factorysetup.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "platform_init.h"
#include "screen.h"
#include "securechip/securechip.h"
#include "system.h"
#include "usb/usb.h"
#include "usb/usb_packet.h"
#include "usb/usb_processing.h"
Expand Down Expand Up @@ -312,19 +313,8 @@ int main(void)
screen_splash();
common_main();

{
// Set to re-enter bootloader again, otherwise we are stuck with this
// firmware forever.
auto_enter_t auto_enter = {
.value = sectrue_u8,
};
upside_down_t upside_down = {
.value = false,
};
if (!memory_bootloader_set_flags(auto_enter, upside_down)) {
// Not much we can do here.
}
}
// After reset we prefer to stay in bootloader
auto_enter = sectrue_u32;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The factory-setup could also just erase the first 8 bytes of itself when it is done, making it unbootable (and thus the bootloader would not try to boot it).


SEGGER_RTT_Init();

Expand Down
22 changes: 6 additions & 16 deletions src/hardfault.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// limitations under the License.

#include "hardfault.h"
#include "system.h"
#include "util.h"
#include "utils_assert.h"
#include <memory/memory.h>
Expand Down Expand Up @@ -47,20 +48,9 @@ void Abort(const char* msg)
#endif
// Break the program if we are debugging
ASSERT(false);
while (1) {
}
}

void AbortAutoenter(const char* msg)
{
auto_enter_t auto_enter = {
.value = sectrue_u8,
};
upside_down_t upside_down = {
.value = screen_is_upside_down(),
};
if (!memory_bootloader_set_flags(auto_enter, upside_down)) {
// If this failed, we might not be able to reboot into the bootloader.
}
Abort(msg);
delay_ms(30000);
// Restart into bootloader
auto_enter = sectrue_u32;
_reset_mcu();
while (1);
}
7 changes: 0 additions & 7 deletions src/hardfault.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,4 @@ void HardFault_Handler(void) __attribute__((weak));
// debugging.
__attribute__((noreturn)) void Abort(const char* msg);

// Abort is for manual calls to stop execution, providing a message for debugging. It also sets
// autoenter to true, making sure that the device boots into the bootloader after reconnecting it.
// This should be called for any Abort during firmware startup, so a firmware update can be
// applied. Otherwise, if there is an Abort() during startup, there would no way to reboot into the
// bootloader and the device would be bricked.
__attribute__((noreturn)) void AbortAutoenter(const char* msg);

#endif
2 changes: 1 addition & 1 deletion src/memory/bitbox02_smarteeprom.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ void bitbox02_smarteeprom_init(void)
*/
char msg[200] = {0};
snprintf(msg, sizeof(msg), "Unrecognized SmartEEPROM version.\nGot %d", current_version);
AbortAutoenter(msg);
Abort(msg);
}
}

Expand Down
14 changes: 4 additions & 10 deletions src/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,16 @@
#include "system.h"
#include <memory/memory.h>
#include <screen.h>
#include <stdint.h>
#ifndef TESTING
#include <driver_init.h>
#endif

volatile secbool_u32 auto_enter __attribute__((section(".auto_enter")));

void reboot(void)
{
auto_enter_t auto_enter = {
.value = sectrue_u8,
};
upside_down_t upside_down = {
.value = screen_is_upside_down(),
};
if (!memory_bootloader_set_flags(auto_enter, upside_down)) {
// If this failed, we might not be able to reboot into the bootloader.
// We will try anyway, no point in aborting here.
}
auto_enter = sectrue_u32;
#ifndef TESTING
_reset_mcu();
#endif
Expand Down
8 changes: 7 additions & 1 deletion src/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,14 @@
#ifndef _SYSTEM_H_
#define _SYSTEM_H_

#include "util.h"

// Set this to `sectrue_u32` to stay in bootloader, or anything else to jump to firmware

extern volatile secbool_u32 auto_enter;

/**
* Reboots the device.
* Reboots the device into bootloader
*/
void reboot(void);

Expand Down
Loading