mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-22 23:48:12 +00:00
bootloader: implement WipeDevice
This commit is contained in:
parent
5bec30e0dc
commit
82050912c4
@ -42,7 +42,7 @@ static uint32_t check_sdcard(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void progress_callback(uint16_t val) {
|
||||
static void progress_callback(int pos, int len) {
|
||||
display_printf(".");
|
||||
}
|
||||
|
||||
@ -72,7 +72,30 @@ static bool copy_sdcard(void)
|
||||
display_printf("\n\nerasing flash:\n\n");
|
||||
|
||||
// erase all flash (except boardloader)
|
||||
if (!flash_erase_sectors(FLASH_SECTOR_BOARDLOADER_END + 1, FLASH_SECTOR_LAST, progress_callback)) {
|
||||
uint8_t sectors[] = {
|
||||
FLASH_SECTOR_STORAGE_1,
|
||||
FLASH_SECTOR_STORAGE_2,
|
||||
FLASH_SECTOR_PIN_AREA,
|
||||
FLASH_SECTOR_BOOTLOADER,
|
||||
FLASH_SECTOR_FIRMWARE_START,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
FLASH_SECTOR_FIRMWARE_END,
|
||||
FLASH_SECTOR_UNUSED_START,
|
||||
13,
|
||||
14,
|
||||
FLASH_SECTOR_UNUSED_END,
|
||||
FLASH_SECTOR_FIRMWARE_EXTRA_START,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
FLASH_SECTOR_FIRMWARE_EXTRA_END,
|
||||
};
|
||||
if (!flash_erase_sectors(sectors, 2 + 1 + 1 + 6 + 4 + 7, progress_callback)) {
|
||||
display_printf(" failed\n");
|
||||
return false;
|
||||
}
|
||||
@ -130,8 +153,8 @@ int main(void)
|
||||
#if PRODUCTION
|
||||
flash_set_option_bytes();
|
||||
if (!flash_check_option_bytes()) {
|
||||
flash_erase_sectors(FLASH_SECTOR_STORAGE_1, FLASH_SECTOR_STORAGE_1, NULL);
|
||||
flash_erase_sectors(FLASH_SECTOR_STORAGE_2, FLASH_SECTOR_STORAGE_2, NULL);
|
||||
uint8_t sectors[] = {FLASH_SECTOR_STORAGE_1, FLASH_SECTOR_STORAGE_2};
|
||||
flash_erase_sectors(sectors, 2, NULL);
|
||||
ensure(0, "wrong option bytes");
|
||||
}
|
||||
#endif
|
||||
|
@ -144,19 +144,36 @@ void bootloader_loop(void)
|
||||
case 1: // Ping
|
||||
process_msg_Ping(USB_IFACE_NUM, msg_size, buf);
|
||||
break;
|
||||
case 5: // WipeDevice
|
||||
display_clear();
|
||||
display_text_center(120, 30, "Wiping Device", -1, FONT_BOLD, COLOR_WHITE, COLOR_BLACK);
|
||||
r = process_msg_WipeDevice(USB_IFACE_NUM, msg_size, buf);
|
||||
if (r < 0) { // error
|
||||
display_clear();
|
||||
display_text_center(120, 30, "Error", -1, FONT_BOLD, COLOR_RED, COLOR_BLACK);
|
||||
display_loader(1000, 0, COLOR_RED, COLOR_BLACK, 0, 0, 0);
|
||||
} else { // success
|
||||
display_clear();
|
||||
display_text_center(120, 30, "Done", -1, FONT_BOLD, COLOR_GREEN, COLOR_BLACK);
|
||||
display_loader(1000, 0, COLOR_GREEN, COLOR_BLACK, 0, 0, 0);
|
||||
}
|
||||
break;
|
||||
case 6: // FirmwareErase
|
||||
display_text_center(120, 230, "Updating firmware", -1, FONT_BOLD, COLOR_WHITE, COLOR_BLACK);
|
||||
display_clear();
|
||||
display_text_center(120, 30, "Updating Firmware", -1, FONT_BOLD, COLOR_WHITE, COLOR_BLACK);
|
||||
process_msg_FirmwareErase(USB_IFACE_NUM, msg_size, buf);
|
||||
break;
|
||||
case 7: // FirmwareUpload
|
||||
r = process_msg_FirmwareUpload(USB_IFACE_NUM, msg_size, buf);
|
||||
if (r < 0) { // error
|
||||
display_clear();
|
||||
display_text_center(120, 230, "Error", -1, FONT_BOLD, COLOR_WHITE, COLOR_BLACK);
|
||||
display_text_center(120, 30, "Error", -1, FONT_BOLD, COLOR_RED, COLOR_BLACK);
|
||||
display_loader(1000, 0, COLOR_RED, COLOR_BLACK, 0, 0, 0);
|
||||
} else
|
||||
if (r == 0) { // last chunk received
|
||||
display_clear();
|
||||
display_text_center(120, 230, "Done", -1, FONT_BOLD, COLOR_WHITE, COLOR_BLACK);
|
||||
display_text_center(120, 30, "Done", -1, FONT_BOLD, COLOR_GREEN, COLOR_BLACK);
|
||||
display_loader(1000, 0, COLOR_GREEN, COLOR_BLACK, 0, 0, 0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -201,13 +218,16 @@ int main(void)
|
||||
|
||||
ensure(0 == touch_init(), NULL);
|
||||
|
||||
uint32_t touched = 0;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
touched |= touch_read();
|
||||
// delay to detect touch
|
||||
hal_delay(100);
|
||||
bool touched = false;
|
||||
// flush touch events
|
||||
while (touch_read()) {
|
||||
touched = true;
|
||||
}
|
||||
|
||||
// start the bootloader if user touched the screen or no firmware installed
|
||||
if (touched != 0 || !vendor_parse_header((const uint8_t *)FIRMWARE_START, NULL)) {
|
||||
if (touched || !vendor_parse_header((const uint8_t *)FIRMWARE_START, NULL)) {
|
||||
bootloader_loop();
|
||||
shutdown();
|
||||
}
|
||||
|
@ -228,9 +228,9 @@ void process_msg_Ping(uint8_t iface_num, uint32_t msg_size, uint8_t *buf)
|
||||
|
||||
static uint32_t firmware_remaining, firmware_flashed, chunk_requested;
|
||||
|
||||
static void progress_erase(uint16_t val)
|
||||
static void progress_erase(int pos, int len)
|
||||
{
|
||||
display_loader(val / 4, 0, 0xFFFF, 0, 0, 0, 0);
|
||||
display_loader(250 * pos / len, 0, COLOR_WHITE, COLOR_BLACK, 0, 0, 0);
|
||||
}
|
||||
|
||||
void process_msg_FirmwareErase(uint8_t iface_num, uint32_t msg_size, uint8_t *buf)
|
||||
@ -245,7 +245,22 @@ void process_msg_FirmwareErase(uint8_t iface_num, uint32_t msg_size, uint8_t *bu
|
||||
firmware_remaining = msg_recv.has_length ? msg_recv.length : 0;
|
||||
if (firmware_remaining > 0 && firmware_remaining % 4 == 0) {
|
||||
// erase flash
|
||||
if (!flash_erase_sectors(FLASH_SECTOR_FIRMWARE_START, FLASH_SECTOR_FIRMWARE_END, progress_erase)) {
|
||||
uint8_t sectors[] = {
|
||||
FLASH_SECTOR_FIRMWARE_START,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
FLASH_SECTOR_FIRMWARE_END,
|
||||
FLASH_SECTOR_FIRMWARE_EXTRA_START,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
FLASH_SECTOR_FIRMWARE_EXTRA_END,
|
||||
};
|
||||
if (!flash_erase_sectors(sectors, 6 + 7, progress_erase)) {
|
||||
MSG_SEND_INIT(Failure);
|
||||
MSG_SEND_ASSIGN_VALUE(code, FailureType_Failure_ProcessError);
|
||||
MSG_SEND_ASSIGN_STRING(message, "Could not erase flash");
|
||||
@ -276,7 +291,7 @@ static bool _read_payload(pb_istream_t *stream, const pb_field_t *field, void **
|
||||
chunk_size = stream->bytes_left;
|
||||
while (stream->bytes_left) {
|
||||
// print loader
|
||||
display_loader(250 + 750 * (firmware_flashed + chunk_written) / (firmware_flashed + firmware_remaining), 0, 0xFFFF, 0, 0, 0, 0);
|
||||
display_loader(250 + 750 * (firmware_flashed + chunk_written) / (firmware_flashed + firmware_remaining), 0, COLOR_WHITE, COLOR_BLACK, 0, 0, 0);
|
||||
memset(buf, 0xFF, sizeof(buf));
|
||||
// read data
|
||||
if (!pb_read(stream, (pb_byte_t *)buf, (stream->bytes_left > BUFSIZE) ? BUFSIZE : stream->bytes_left)) {
|
||||
@ -331,6 +346,48 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, uint8_t *bu
|
||||
return (int)firmware_remaining;
|
||||
}
|
||||
|
||||
static void progress_wipe(int pos, int len)
|
||||
{
|
||||
display_loader(1000 * pos / len, 0, COLOR_WHITE, COLOR_BLACK, 0, 0, 0);
|
||||
}
|
||||
|
||||
int process_msg_WipeDevice(uint8_t iface_num, uint32_t msg_size, uint8_t *buf)
|
||||
{
|
||||
uint8_t sectors[] = {
|
||||
FLASH_SECTOR_STORAGE_1,
|
||||
FLASH_SECTOR_STORAGE_2,
|
||||
FLASH_SECTOR_PIN_AREA,
|
||||
FLASH_SECTOR_FIRMWARE_START,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
FLASH_SECTOR_FIRMWARE_END,
|
||||
FLASH_SECTOR_UNUSED_START,
|
||||
13,
|
||||
14,
|
||||
FLASH_SECTOR_UNUSED_END,
|
||||
FLASH_SECTOR_FIRMWARE_EXTRA_START,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
FLASH_SECTOR_FIRMWARE_EXTRA_END,
|
||||
};
|
||||
if (!flash_erase_sectors(sectors, 2 + 1 + 6 + 4 + 7, progress_wipe)) {
|
||||
MSG_SEND_INIT(Failure);
|
||||
MSG_SEND_ASSIGN_VALUE(code, FailureType_Failure_ProcessError);
|
||||
MSG_SEND_ASSIGN_STRING(message, "Could not erase flash");
|
||||
MSG_SEND(Failure);
|
||||
return -1;
|
||||
} else {
|
||||
MSG_SEND_INIT(Success);
|
||||
MSG_SEND(Success);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void process_msg_unknown(uint8_t iface_num, uint32_t msg_size, uint8_t *buf)
|
||||
{
|
||||
// consume remaining message
|
||||
|
@ -13,6 +13,7 @@ void process_msg_Initialize(uint8_t iface_num, uint32_t msg_size, uint8_t *buf);
|
||||
void process_msg_Ping(uint8_t iface_num, uint32_t msg_size, uint8_t *buf);
|
||||
void process_msg_FirmwareErase(uint8_t iface_num, uint32_t msg_size, uint8_t *buf);
|
||||
int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, uint8_t *buf);
|
||||
int process_msg_WipeDevice(uint8_t iface_num, uint32_t msg_size, uint8_t *buf);
|
||||
void process_msg_unknown(uint8_t iface_num, uint32_t msg_size, uint8_t *buf);
|
||||
|
||||
#endif
|
||||
|
@ -38,8 +38,14 @@
|
||||
#define COLOR_GRAY128 RGB16(127, 127, 127)
|
||||
#define COLOR_GRAY64 RGB16(63, 63, 63)
|
||||
#define COLOR_BLACK RGB16(0, 0, 0)
|
||||
|
||||
#define COLOR_RED RGB16(255, 0, 0)
|
||||
#define COLOR_RED128 RGB16(127, 0, 0)
|
||||
|
||||
#define COLOR_GREEN RGB16(0, 255, 0)
|
||||
#define COLOR_GREEN128 RGB16(0, 127, 0)
|
||||
|
||||
#define COLOR_BLUE RGB16(0, 0, 255)
|
||||
#define COLOR_BLUE128 RGB16(0, 0, 127)
|
||||
|
||||
// provided by port
|
||||
|
@ -21,7 +21,7 @@ bool flash_lock(void)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool flash_erase_sectors(int start, int end, void (*progress)(uint16_t val))
|
||||
bool flash_erase_sectors(const uint8_t *sectors, int len, void (*progress)(int pos, int len))
|
||||
{
|
||||
if (!flash_unlock()) {
|
||||
return false;
|
||||
@ -31,14 +31,17 @@ bool flash_erase_sectors(int start, int end, void (*progress)(uint16_t val))
|
||||
EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
|
||||
EraseInitStruct.NbSectors = 1;
|
||||
uint32_t SectorError = 0;
|
||||
for (int i = start; i <= end; i++) {
|
||||
EraseInitStruct.Sector = i;
|
||||
if (progress) {
|
||||
progress(0, len);
|
||||
}
|
||||
for (int i = 0; i < len; i++) {
|
||||
EraseInitStruct.Sector = sectors[i];
|
||||
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK) {
|
||||
flash_lock();
|
||||
return false;
|
||||
}
|
||||
if (progress) {
|
||||
progress(1000 * (i - start + 1) / (end - start + 1));
|
||||
progress(i + 1, len);
|
||||
}
|
||||
}
|
||||
flash_lock();
|
||||
|
@ -47,7 +47,7 @@ void flash_set_option_bytes(void);
|
||||
bool flash_unlock(void);
|
||||
bool flash_lock(void);
|
||||
|
||||
bool flash_erase_sectors(int start, int end, void (*progress)(uint16_t val));
|
||||
bool flash_erase_sectors(const uint8_t *sectors, int len, void (*progress)(int pos, int len));
|
||||
bool flash_write_byte(uint32_t address, uint8_t data);
|
||||
bool flash_write_word(uint32_t address, uint32_t data);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user