1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-30 03:18:20 +00:00

bootloader: implement WipeDevice

This commit is contained in:
Pavol Rusnak 2017-10-16 20:24:28 +02:00
parent 5bec30e0dc
commit 82050912c4
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
7 changed files with 130 additions and 20 deletions

View File

@ -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("."); display_printf(".");
} }
@ -72,7 +72,30 @@ static bool copy_sdcard(void)
display_printf("\n\nerasing flash:\n\n"); display_printf("\n\nerasing flash:\n\n");
// erase all flash (except boardloader) // 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"); display_printf(" failed\n");
return false; return false;
} }
@ -130,8 +153,8 @@ int main(void)
#if PRODUCTION #if PRODUCTION
flash_set_option_bytes(); flash_set_option_bytes();
if (!flash_check_option_bytes()) { if (!flash_check_option_bytes()) {
flash_erase_sectors(FLASH_SECTOR_STORAGE_1, FLASH_SECTOR_STORAGE_1, NULL); uint8_t sectors[] = {FLASH_SECTOR_STORAGE_1, FLASH_SECTOR_STORAGE_2};
flash_erase_sectors(FLASH_SECTOR_STORAGE_2, FLASH_SECTOR_STORAGE_2, NULL); flash_erase_sectors(sectors, 2, NULL);
ensure(0, "wrong option bytes"); ensure(0, "wrong option bytes");
} }
#endif #endif

View File

@ -144,19 +144,36 @@ void bootloader_loop(void)
case 1: // Ping case 1: // Ping
process_msg_Ping(USB_IFACE_NUM, msg_size, buf); process_msg_Ping(USB_IFACE_NUM, msg_size, buf);
break; 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 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); process_msg_FirmwareErase(USB_IFACE_NUM, msg_size, buf);
break; break;
case 7: // FirmwareUpload case 7: // FirmwareUpload
r = process_msg_FirmwareUpload(USB_IFACE_NUM, msg_size, buf); r = process_msg_FirmwareUpload(USB_IFACE_NUM, msg_size, buf);
if (r < 0) { // error if (r < 0) { // error
display_clear(); 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 } else
if (r == 0) { // last chunk received if (r == 0) { // last chunk received
display_clear(); 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; break;
default: default:
@ -201,13 +218,16 @@ int main(void)
ensure(0 == touch_init(), NULL); ensure(0 == touch_init(), NULL);
uint32_t touched = 0; // delay to detect touch
for (int i = 0; i < 10; i++) { hal_delay(100);
touched |= touch_read(); bool touched = false;
// flush touch events
while (touch_read()) {
touched = true;
} }
// start the bootloader if user touched the screen or no firmware installed // 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(); bootloader_loop();
shutdown(); shutdown();
} }

View File

@ -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 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) 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; firmware_remaining = msg_recv.has_length ? msg_recv.length : 0;
if (firmware_remaining > 0 && firmware_remaining % 4 == 0) { if (firmware_remaining > 0 && firmware_remaining % 4 == 0) {
// erase flash // 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_INIT(Failure);
MSG_SEND_ASSIGN_VALUE(code, FailureType_Failure_ProcessError); MSG_SEND_ASSIGN_VALUE(code, FailureType_Failure_ProcessError);
MSG_SEND_ASSIGN_STRING(message, "Could not erase flash"); 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; chunk_size = stream->bytes_left;
while (stream->bytes_left) { while (stream->bytes_left) {
// print loader // 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)); memset(buf, 0xFF, sizeof(buf));
// read data // read data
if (!pb_read(stream, (pb_byte_t *)buf, (stream->bytes_left > BUFSIZE) ? BUFSIZE : stream->bytes_left)) { 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; 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) void process_msg_unknown(uint8_t iface_num, uint32_t msg_size, uint8_t *buf)
{ {
// consume remaining message // consume remaining message

View File

@ -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_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); 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_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); void process_msg_unknown(uint8_t iface_num, uint32_t msg_size, uint8_t *buf);
#endif #endif

View File

@ -38,8 +38,14 @@
#define COLOR_GRAY128 RGB16(127, 127, 127) #define COLOR_GRAY128 RGB16(127, 127, 127)
#define COLOR_GRAY64 RGB16(63, 63, 63) #define COLOR_GRAY64 RGB16(63, 63, 63)
#define COLOR_BLACK RGB16(0, 0, 0) #define COLOR_BLACK RGB16(0, 0, 0)
#define COLOR_RED RGB16(255, 0, 0)
#define COLOR_RED128 RGB16(127, 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_GREEN128 RGB16(0, 127, 0)
#define COLOR_BLUE RGB16(0, 0, 255)
#define COLOR_BLUE128 RGB16(0, 0, 127) #define COLOR_BLUE128 RGB16(0, 0, 127)
// provided by port // provided by port

View File

@ -21,7 +21,7 @@ bool flash_lock(void)
return true; 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()) { if (!flash_unlock()) {
return false; 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.VoltageRange = FLASH_VOLTAGE_RANGE_3;
EraseInitStruct.NbSectors = 1; EraseInitStruct.NbSectors = 1;
uint32_t SectorError = 0; uint32_t SectorError = 0;
for (int i = start; i <= end; i++) { if (progress) {
EraseInitStruct.Sector = i; progress(0, len);
}
for (int i = 0; i < len; i++) {
EraseInitStruct.Sector = sectors[i];
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK) { if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK) {
flash_lock(); flash_lock();
return false; return false;
} }
if (progress) { if (progress) {
progress(1000 * (i - start + 1) / (end - start + 1)); progress(i + 1, len);
} }
} }
flash_lock(); flash_lock();

View File

@ -47,7 +47,7 @@ void flash_set_option_bytes(void);
bool flash_unlock(void); bool flash_unlock(void);
bool flash_lock(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_byte(uint32_t address, uint8_t data);
bool flash_write_word(uint32_t address, uint32_t data); bool flash_write_word(uint32_t address, uint32_t data);