|
|
|
|
@@ -428,21 +428,24 @@ static int get_proxmark_state(uint32_t *state) {
|
|
|
|
|
|
|
|
|
|
// Enter the bootloader to be able to start flashing
|
|
|
|
|
static int enter_bootloader(char *serial_port_name, bool wait_appear) {
|
|
|
|
|
uint32_t state;
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
if ((ret = get_proxmark_state(&state)) != PM3_SUCCESS)
|
|
|
|
|
uint32_t state = 0;
|
|
|
|
|
int ret = get_proxmark_state(&state);
|
|
|
|
|
if (ret != PM3_SUCCESS) {
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Already in flash state, we're done. */
|
|
|
|
|
if (state & DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM)
|
|
|
|
|
if ((state & DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM) == DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM) {
|
|
|
|
|
return PM3_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (state & DEVICE_INFO_FLAG_CURRENT_MODE_OS) {
|
|
|
|
|
if ((state & DEVICE_INFO_FLAG_CURRENT_MODE_OS) == DEVICE_INFO_FLAG_CURRENT_MODE_OS) {
|
|
|
|
|
PrintAndLogEx(SUCCESS, _CYAN_("Entering bootloader..."));
|
|
|
|
|
|
|
|
|
|
if ((state & DEVICE_INFO_FLAG_BOOTROM_PRESENT)
|
|
|
|
|
&& (state & DEVICE_INFO_FLAG_OSIMAGE_PRESENT)) {
|
|
|
|
|
if (
|
|
|
|
|
((state & DEVICE_INFO_FLAG_BOOTROM_PRESENT) == DEVICE_INFO_FLAG_BOOTROM_PRESENT) &&
|
|
|
|
|
((state & DEVICE_INFO_FLAG_OSIMAGE_PRESENT) == DEVICE_INFO_FLAG_OSIMAGE_PRESENT)) {
|
|
|
|
|
// New style handover: Send CMD_START_FLASH, which will reset the board
|
|
|
|
|
// and enter the bootrom on the next boot.
|
|
|
|
|
SendCommandBL(CMD_START_FLASH, 0, 0, 0, NULL, 0);
|
|
|
|
|
@@ -453,6 +456,7 @@ static int enter_bootloader(char *serial_port_name, bool wait_appear) {
|
|
|
|
|
PrintAndLogEx(SUCCESS, "Press and hold down button NOW if your bootloader requires it.");
|
|
|
|
|
}
|
|
|
|
|
msleep(500);
|
|
|
|
|
PrintAndLogEx(SUCCESS, _CYAN_("Trigger restart..."));
|
|
|
|
|
CloseProxmark(g_session.current_device);
|
|
|
|
|
// Let time to OS to make the port disappear
|
|
|
|
|
msleep(1000);
|
|
|
|
|
@@ -487,8 +491,9 @@ static int wait_for_ack(PacketResponseNG *ack) {
|
|
|
|
|
|
|
|
|
|
static bool gs_printed_msg = false;
|
|
|
|
|
static void flash_suggest_update_bootloader(void) {
|
|
|
|
|
if (gs_printed_msg)
|
|
|
|
|
if (gs_printed_msg) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PrintAndLogEx(ERR, _RED_("It is recommended that you first" _YELLOW_(" update your bootloader") _RED_(" alone,")));
|
|
|
|
|
PrintAndLogEx(ERR, _RED_("reboot the Proxmark3 then only update the main firmware") "\n");
|
|
|
|
|
@@ -510,19 +515,21 @@ static void flash_suggest_update_flasher(void) {
|
|
|
|
|
|
|
|
|
|
// Go into flashing mode
|
|
|
|
|
int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t *max_allowed) {
|
|
|
|
|
|
|
|
|
|
int ret = enter_bootloader(serial_port_name, true);
|
|
|
|
|
if (ret != PM3_SUCCESS) {
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t state;
|
|
|
|
|
uint32_t chipinfo = 0;
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
ret = enter_bootloader(serial_port_name, true);
|
|
|
|
|
if (ret != PM3_SUCCESS)
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
ret = get_proxmark_state(&state);
|
|
|
|
|
if (ret != PM3_SUCCESS)
|
|
|
|
|
if (ret != PM3_SUCCESS) {
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (state & DEVICE_INFO_FLAG_UNDERSTANDS_CHIP_INFO) {
|
|
|
|
|
uint32_t chipinfo = 0;
|
|
|
|
|
|
|
|
|
|
if ((state & DEVICE_INFO_FLAG_UNDERSTANDS_CHIP_INFO) == DEVICE_INFO_FLAG_UNDERSTANDS_CHIP_INFO) {
|
|
|
|
|
SendCommandBL(CMD_CHIP_INFO, 0, 0, 0, NULL, 0);
|
|
|
|
|
PacketResponseNG resp;
|
|
|
|
|
WaitForResponse(CMD_CHIP_INFO, &resp);
|
|
|
|
|
@@ -530,11 +537,14 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int version = BL_VERSION_INVALID;
|
|
|
|
|
if (state & DEVICE_INFO_FLAG_UNDERSTANDS_VERSION) {
|
|
|
|
|
|
|
|
|
|
if ((state & DEVICE_INFO_FLAG_UNDERSTANDS_VERSION) == DEVICE_INFO_FLAG_UNDERSTANDS_VERSION) {
|
|
|
|
|
|
|
|
|
|
SendCommandBL(CMD_BL_VERSION, 0, 0, 0, NULL, 0);
|
|
|
|
|
PacketResponseNG resp;
|
|
|
|
|
WaitForResponse(CMD_BL_VERSION, &resp);
|
|
|
|
|
version = resp.oldarg[0];
|
|
|
|
|
|
|
|
|
|
if ((BL_VERSION_MAJOR(version) < BL_VERSION_FIRST_MAJOR) || (BL_VERSION_MAJOR(version) > BL_VERSION_LAST_MAJOR)) {
|
|
|
|
|
// version info seems fishy
|
|
|
|
|
version = BL_VERSION_INVALID;
|
|
|
|
|
@@ -562,7 +572,9 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t
|
|
|
|
|
|
|
|
|
|
int mem_avail = chipid_to_mem_avail(chipinfo);
|
|
|
|
|
if (mem_avail != 0) {
|
|
|
|
|
|
|
|
|
|
PrintAndLogEx(INFO, "Available memory on this board: "_YELLOW_("%uK") " bytes\n", mem_avail);
|
|
|
|
|
|
|
|
|
|
if (mem_avail > 256) {
|
|
|
|
|
if (BL_VERSION_MAJOR(version) < BL_VERSION_MAJOR(BL_VERSION_1_0_0)) {
|
|
|
|
|
PrintAndLogEx(ERR, _RED_("====================== OBS ! ======================"));
|
|
|
|
|
@@ -573,6 +585,7 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t
|
|
|
|
|
*max_allowed = mem_avail;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
PrintAndLogEx(INFO, "Available memory on this board: "_RED_("UNKNOWN")"\n");
|
|
|
|
|
PrintAndLogEx(ERR, _RED_("====================== OBS ! ======================================"));
|
|
|
|
|
@@ -585,15 +598,17 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t
|
|
|
|
|
} else {
|
|
|
|
|
PrintAndLogEx(INFO, "Permitted flash range: 0x%08x-0x%08x", BOOTLOADER_END, flash_end);
|
|
|
|
|
}
|
|
|
|
|
if (state & DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH) {
|
|
|
|
|
PacketResponseNG resp;
|
|
|
|
|
|
|
|
|
|
if ((state & DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH) == DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH) {
|
|
|
|
|
|
|
|
|
|
if (enable_bl_writes) {
|
|
|
|
|
SendCommandBL(CMD_START_FLASH, FLASH_START, flash_end, START_FLASH_MAGIC, NULL, 0);
|
|
|
|
|
} else {
|
|
|
|
|
SendCommandBL(CMD_START_FLASH, BOOTLOADER_END, flash_end, 0, NULL, 0);
|
|
|
|
|
}
|
|
|
|
|
PacketResponseNG resp;
|
|
|
|
|
return wait_for_ack(&resp);
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
PrintAndLogEx(ERR, _RED_("====================== OBS ! ========================================"));
|
|
|
|
|
PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new" _YELLOW_(" START_FLASH") _RED_(" command")));
|
|
|
|
|
@@ -664,8 +679,9 @@ int flash_write(flash_file_t *ctx) {
|
|
|
|
|
|
|
|
|
|
while (length) {
|
|
|
|
|
uint32_t block_size = length;
|
|
|
|
|
if (block_size > BLOCK_SIZE)
|
|
|
|
|
if (block_size > BLOCK_SIZE) {
|
|
|
|
|
block_size = BLOCK_SIZE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (write_block(baddr, data, block_size) < 0) {
|
|
|
|
|
PrintAndLogEx(ERR, "Error writing block %d of %u", block, blocks);
|
|
|
|
|
@@ -676,9 +692,11 @@ int flash_write(flash_file_t *ctx) {
|
|
|
|
|
baddr += block_size;
|
|
|
|
|
length -= block_size;
|
|
|
|
|
block++;
|
|
|
|
|
|
|
|
|
|
if (len < ice3len) {
|
|
|
|
|
fprintf(stdout, "%c", ice3[len++]);
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
if ((len - ice3len) % 67 == 0) {
|
|
|
|
|
fprintf(stdout, "\n");
|
|
|
|
|
}
|
|
|
|
|
@@ -695,21 +713,29 @@ int flash_write(flash_file_t *ctx) {
|
|
|
|
|
|
|
|
|
|
// free a file context
|
|
|
|
|
void flash_free(flash_file_t *ctx) {
|
|
|
|
|
if (!ctx)
|
|
|
|
|
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ctx->filename != NULL) {
|
|
|
|
|
free(ctx->filename);
|
|
|
|
|
ctx->filename = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ctx->elf) {
|
|
|
|
|
free(ctx->elf);
|
|
|
|
|
ctx->elf = NULL;
|
|
|
|
|
ctx->phdrs = NULL;
|
|
|
|
|
ctx->num_phdrs = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ctx->segments) {
|
|
|
|
|
for (int i = 0; i < ctx->num_segs; i++)
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < ctx->num_segs; i++) {
|
|
|
|
|
free(ctx->segments[i].data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(ctx->segments);
|
|
|
|
|
ctx->segments = NULL;
|
|
|
|
|
ctx->num_segs = 0;
|
|
|
|
|
|