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:
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(".");
|
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
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user