mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-14 10:37:23 -07:00
Bootrom & flasher changes:
* use macros for versions * activate UNDERSTANDS_VERSION in bootrom * fix missing break; bug in bootrom * force flash_load to reject images > 256k if bootloader not up to date * move logic from flasher to flash
This commit is contained in:
parent
68aa9d631d
commit
daae890667
6 changed files with 105 additions and 77 deletions
107
client/flash.c
107
client/flash.c
|
@ -17,6 +17,8 @@
|
|||
|
||||
#define BLOCK_SIZE 0x200
|
||||
|
||||
#define FLASHER_VERSION BL_VERSION_1_0_0
|
||||
|
||||
static const uint8_t elf_ident[] = {
|
||||
0x7f, 'E', 'L', 'F',
|
||||
ELFCLASS32,
|
||||
|
@ -24,6 +26,42 @@ static const uint8_t elf_ident[] = {
|
|||
EV_CURRENT
|
||||
};
|
||||
|
||||
static int chipid_to_mem_avail(uint32_t iChipID) {
|
||||
int mem_avail = 0;
|
||||
switch ((iChipID & 0xF00) >> 8) {
|
||||
case 0:
|
||||
mem_avail = 0;
|
||||
break;
|
||||
case 1:
|
||||
mem_avail = 8;
|
||||
break;
|
||||
case 2:
|
||||
mem_avail = 16;
|
||||
break;
|
||||
case 3:
|
||||
mem_avail = 32;
|
||||
break;
|
||||
case 5:
|
||||
mem_avail = 64;
|
||||
break;
|
||||
case 7:
|
||||
mem_avail = 128;
|
||||
break;
|
||||
case 9:
|
||||
mem_avail = 256;
|
||||
break;
|
||||
case 10:
|
||||
mem_avail = 512;
|
||||
break;
|
||||
case 12:
|
||||
mem_avail = 1024;
|
||||
break;
|
||||
case 14:
|
||||
mem_avail = 2048;
|
||||
}
|
||||
return mem_avail;
|
||||
}
|
||||
|
||||
// Turn PHDRs into flasher segments, checking for PHDR sanity and merging adjacent
|
||||
// unaligned segments if needed
|
||||
static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, uint16_t num_phdrs, uint32_t flash_end) {
|
||||
|
@ -339,9 +377,19 @@ static int wait_for_ack(PacketResponseNG *ack) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void flash_suggest_update_bootloader(void) {
|
||||
PrintAndLogEx(ERR, _RED_("It is recommended that you first update your bootloader alone,"));
|
||||
PrintAndLogEx(ERR, _RED_("reboot the Proxmark3 then only update the main firmware") "\n");
|
||||
}
|
||||
|
||||
static void flash_suggest_update_flasher(void) {
|
||||
PrintAndLogEx(ERR, _RED_("It is recommended that you first update your flasher"));
|
||||
}
|
||||
|
||||
// Go into flashing mode
|
||||
int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t *chipinfo) {
|
||||
int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t *max_allowed) {
|
||||
uint32_t state;
|
||||
uint32_t chipinfo = 0;
|
||||
|
||||
if (enter_bootloader(serial_port_name) < 0)
|
||||
return -1;
|
||||
|
@ -353,7 +401,7 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t
|
|||
SendCommandBL(CMD_CHIP_INFO, 0, 0, 0, NULL, 0);
|
||||
PacketResponseNG resp;
|
||||
WaitForResponse(CMD_CHIP_INFO, &resp);
|
||||
*chipinfo = resp.oldarg[0];
|
||||
chipinfo = resp.oldarg[0];
|
||||
}
|
||||
|
||||
int version = BL_VERSION_INVALID;
|
||||
|
@ -362,32 +410,51 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t
|
|||
PacketResponseNG resp;
|
||||
WaitForResponse(CMD_BL_VERSION, &resp);
|
||||
version = resp.oldarg[0];
|
||||
if ((version < BL_VERSION_FIRST || version > BL_VERSION_LAST)) {
|
||||
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;
|
||||
PrintAndLogEx(ERR, _RED_("Note: Your bootloader reported an invalid version number"));
|
||||
flash_suggest_update_bootloader();
|
||||
//
|
||||
} else if (BL_VERSION_MAJOR(version) < BL_VERSION_MAJOR(FLASHER_VERSION)) {
|
||||
PrintAndLogEx(ERR, _RED_("Note: Your bootloader reported a version older than this flasher"));
|
||||
flash_suggest_update_bootloader();
|
||||
} else if (BL_VERSION_MAJOR(version) > BL_VERSION_MAJOR(FLASHER_VERSION)) {
|
||||
PrintAndLogEx(ERR, _RED_("Note: Your bootloader is more recent than this flasher"));
|
||||
flash_suggest_update_flasher();
|
||||
}
|
||||
} else {
|
||||
PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new CMD_BL_VERSION command"));
|
||||
PrintAndLogEx(ERR, _RED_("It is recommended that you update your bootloader") "\n");
|
||||
}
|
||||
|
||||
bool allow_512k_writes = false;
|
||||
if (version == BL_VERSION_INVALID) {
|
||||
PrintAndLogEx(ERR, _RED_("Note: Your bootloader reported an invalid version number"));
|
||||
PrintAndLogEx(ERR, _RED_("It is recommended that you update your bootloader") "\n");
|
||||
} else if (version >= BL_VERSION_1_0_0) {
|
||||
allow_512k_writes = true;
|
||||
flash_suggest_update_bootloader();
|
||||
}
|
||||
|
||||
uint32_t flash_end = FLASH_START + AT91C_IFLASH_PAGE_SIZE * AT91C_IFLASH_NB_OF_PAGES / 2;
|
||||
if ((((*chipinfo & 0xF00) >> 8) > 9) && allow_512k_writes) {
|
||||
flash_end = FLASH_START + AT91C_IFLASH_PAGE_SIZE * AT91C_IFLASH_NB_OF_PAGES;
|
||||
*max_allowed = 256;
|
||||
|
||||
int mem_avail = chipid_to_mem_avail(chipinfo);
|
||||
if (mem_avail != 0) {
|
||||
PrintAndLogEx(NORMAL, "Available memory on this board: %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_("Your bootloader does not support writing above 256k"));
|
||||
flash_suggest_update_bootloader();
|
||||
} else {
|
||||
flash_end = FLASH_START + AT91C_IFLASH_PAGE_SIZE * AT91C_IFLASH_NB_OF_PAGES;
|
||||
*max_allowed = mem_avail;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
PrintAndLogEx(NORMAL, "Available memory on this board: "_RED_("UNKNOWN")"\n");
|
||||
PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new CHIP_INFO command"));
|
||||
flash_suggest_update_bootloader();
|
||||
}
|
||||
|
||||
if (enable_bl_writes) {
|
||||
PrintAndLogEx(INFO, "Permitted flash range: 0x%08x-0x%08x", FLASH_START, flash_end);
|
||||
} else {
|
||||
PrintAndLogEx(INFO, "Permitted flash range: 0x%08x-0x%08x", BOOTLOADER_END, flash_end);
|
||||
}
|
||||
|
||||
PrintAndLogEx(INFO, "End of flash: 0x%08x", flash_end);
|
||||
|
||||
if (state & DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH) {
|
||||
// This command is stupid. Why the heck does it care which area we're
|
||||
// flashing, as long as it's not the bootloader area? The mind boggles.
|
||||
PacketResponseNG resp;
|
||||
|
||||
if (enable_bl_writes) {
|
||||
|
@ -398,7 +465,7 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t
|
|||
return wait_for_ack(&resp);
|
||||
} else {
|
||||
PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new START_FLASH command"));
|
||||
PrintAndLogEx(ERR, _RED_("It is recommended that you update your bootloader") "\n");
|
||||
flash_suggest_update_bootloader();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue