mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-01-31 04:20:28 +08:00
Flasher support for 512K flash
A better way would be to cut the connecting function and flashing function and to move the whole mem computation to flash.c Working flasher
This commit is contained in:
parent
4e9e7d6da0
commit
7bf3255a6c
5 changed files with 52 additions and 35 deletions
|
@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.
|
|||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||
|
||||
## [unreleased][unreleased]
|
||||
- Add support for flashing 512K units (@slurdge)
|
||||
- Add a simple python tool to check the elf sizes (@slurdge)
|
||||
- Change: new keys for Vigik badges in default_keys.dict (@luminouw)
|
||||
- Add 'hw standalone' to jump to standalone mode from command line or script (@doegox)
|
||||
|
|
|
@ -153,28 +153,35 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
|||
case CMD_FINISH_WRITE: {
|
||||
uint32_t *flash_mem = (uint32_t *)(&_flash_start);
|
||||
for (int j = 0; j < 2; j++) {
|
||||
for (i = 0 + (64 * j); i < 64 + (64 * j); i++) {
|
||||
flash_mem[i] = c->d.asDwords[i];
|
||||
}
|
||||
|
||||
uint32_t flash_address = arg0 + (0x100 * j);
|
||||
|
||||
AT91PS_EFC efc_bank = AT91C_BASE_EFC0;
|
||||
int offset = 0;
|
||||
uint32_t page_n = (flash_address - ((uint32_t)flash_mem)) / AT91C_IFLASH_PAGE_SIZE;
|
||||
if (page_n >= AT91C_IFLASH_NB_OF_PAGES / 2) {
|
||||
page_n -= AT91C_IFLASH_NB_OF_PAGES / 2;
|
||||
efc_bank = AT91C_BASE_EFC1;
|
||||
// We need to offset the writes or it will not fill the correct bank write buffer.
|
||||
offset = (AT91C_IFLASH_NB_OF_PAGES / 2) * AT91C_IFLASH_PAGE_SIZE / sizeof(uint32_t);
|
||||
}
|
||||
for (i = 0 + (64 * j); i < 64 + (64 * j); i++) {
|
||||
flash_mem[offset+i] = c->d.asDwords[i];
|
||||
}
|
||||
|
||||
/* Check that the address that we are supposed to write to is within our allowed region */
|
||||
if (((flash_address + AT91C_IFLASH_PAGE_SIZE - 1) >= end_addr) || (flash_address < start_addr)) {
|
||||
/* Disallow write */
|
||||
dont_ack = 1;
|
||||
reply_old(CMD_NACK, 0, 0, 0, 0, 0);
|
||||
} else {
|
||||
uint32_t page_n = (flash_address - ((uint32_t)flash_mem)) / AT91C_IFLASH_PAGE_SIZE;
|
||||
/* Translate address to flash page and do flash, update here for the 512k part */
|
||||
AT91C_BASE_EFC0->EFC_FCR = MC_FLASH_COMMAND_KEY |
|
||||
MC_FLASH_COMMAND_PAGEN(page_n) |
|
||||
AT91C_MC_FCMD_START_PROG;
|
||||
|
||||
efc_bank->EFC_FCR = MC_FLASH_COMMAND_KEY |
|
||||
MC_FLASH_COMMAND_PAGEN(page_n) |
|
||||
AT91C_MC_FCMD_START_PROG;
|
||||
}
|
||||
|
||||
// Wait until flashing of page finishes
|
||||
uint32_t sr;
|
||||
while (!((sr = AT91C_BASE_EFC0->EFC_FSR) & AT91C_MC_FRDY));
|
||||
while (!((sr = efc_bank->EFC_FSR) & AT91C_MC_FRDY));
|
||||
if (sr & (AT91C_MC_LOCKE | AT91C_MC_PROGE)) {
|
||||
dont_ack = 1;
|
||||
reply_old(CMD_NACK, sr, 0, 0, 0, 0);
|
||||
|
|
|
@ -12,13 +12,6 @@
|
|||
|
||||
#define FLASH_START 0x100000
|
||||
|
||||
#ifdef HAS_512_FLASH
|
||||
# define FLASH_SIZE (512*1024)
|
||||
#else
|
||||
# define FLASH_SIZE (256*1024)
|
||||
#endif
|
||||
|
||||
#define FLASH_END (FLASH_START + FLASH_SIZE)
|
||||
#define BOOTLOADER_SIZE 0x2000
|
||||
#define BOOTLOADER_END (FLASH_START + BOOTLOADER_SIZE)
|
||||
|
||||
|
@ -33,7 +26,7 @@ static const uint8_t elf_ident[] = {
|
|||
|
||||
// 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) {
|
||||
static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs, uint16_t num_phdrs, uint32_t flash_end) {
|
||||
Elf32_Phdr *phdr = phdrs;
|
||||
flash_seg_t *seg;
|
||||
uint32_t last_end = 0;
|
||||
|
@ -77,11 +70,11 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs,
|
|||
PrintAndLogEx(ERR, "Error: PHDRs not sorted or overlap");
|
||||
return -1;
|
||||
}
|
||||
if (paddr < FLASH_START || (paddr + filesz) > FLASH_END) {
|
||||
if (paddr < FLASH_START || (paddr + filesz) > flash_end) {
|
||||
PrintAndLogEx(ERR, "Error: PHDR is not contained in Flash");
|
||||
return -1;
|
||||
}
|
||||
if (vaddr >= FLASH_START && vaddr < FLASH_END && (flags & PF_W)) {
|
||||
if (vaddr >= FLASH_START && vaddr < flash_end && (flags & PF_W)) {
|
||||
PrintAndLogEx(ERR, "Error: Flash VMA segment is writable");
|
||||
return -1;
|
||||
}
|
||||
|
@ -153,7 +146,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs,
|
|||
}
|
||||
|
||||
// Sanity check segments and check for bootloader writes
|
||||
static int check_segs(flash_file_t *ctx, int can_write_bl) {
|
||||
static int check_segs(flash_file_t *ctx, int can_write_bl, uint32_t flash_end) {
|
||||
for (int i = 0; i < ctx->num_segs; i++) {
|
||||
flash_seg_t *seg = &ctx->segments[i];
|
||||
|
||||
|
@ -165,7 +158,7 @@ static int check_segs(flash_file_t *ctx, int can_write_bl) {
|
|||
PrintAndLogEx(ERR, "Error: Segment is outside of flash bounds");
|
||||
return -1;
|
||||
}
|
||||
if (seg->start + seg->length > FLASH_END) {
|
||||
if (seg->start + seg->length > flash_end) {
|
||||
PrintAndLogEx(ERR, "Error: Segment is outside of flash bounds");
|
||||
return -1;
|
||||
}
|
||||
|
@ -182,11 +175,12 @@ static int check_segs(flash_file_t *ctx, int can_write_bl) {
|
|||
}
|
||||
|
||||
// Load an ELF file and prepare it for flashing
|
||||
int flash_load(flash_file_t *ctx, const char *name, int can_write_bl) {
|
||||
int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_size) {
|
||||
FILE *fd;
|
||||
Elf32_Ehdr ehdr;
|
||||
Elf32_Phdr *phdrs = NULL;
|
||||
uint16_t num_phdrs;
|
||||
uint32_t flash_end = FLASH_START + flash_size;
|
||||
int res;
|
||||
|
||||
fd = fopen(name, "rb");
|
||||
|
@ -239,10 +233,10 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl) {
|
|||
goto fail;
|
||||
}
|
||||
|
||||
res = build_segs_from_phdrs(ctx, fd, phdrs, num_phdrs);
|
||||
res = build_segs_from_phdrs(ctx, fd, phdrs, num_phdrs, flash_end);
|
||||
if (res < 0)
|
||||
goto fail;
|
||||
res = check_segs(ctx, can_write_bl);
|
||||
res = check_segs(ctx, can_write_bl, flash_end);
|
||||
if (res < 0)
|
||||
goto fail;
|
||||
|
||||
|
@ -362,15 +356,22 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t
|
|||
*chipinfo = resp.oldarg[0];
|
||||
}
|
||||
|
||||
uint32_t flash_end = FLASH_START + AT91C_IFLASH_PAGE_SIZE * AT91C_IFLASH_NB_OF_PAGES / 2;
|
||||
if (((*chipinfo & 0xF00) >> 8) > 9) {
|
||||
flash_end = FLASH_START + AT91C_IFLASH_PAGE_SIZE * AT91C_IFLASH_NB_OF_PAGES;
|
||||
}
|
||||
|
||||
PrintAndLogEx(INFO, "End of flahs: 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) {
|
||||
SendCommandBL(CMD_START_FLASH, FLASH_START, FLASH_END, START_FLASH_MAGIC, NULL, 0);
|
||||
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);
|
||||
SendCommandBL(CMD_START_FLASH, BOOTLOADER_END, flash_end, 0, NULL, 0);
|
||||
}
|
||||
return wait_for_ack(&resp);
|
||||
} else {
|
||||
|
|
|
@ -37,7 +37,7 @@ typedef struct {
|
|||
flash_seg_t *segments;
|
||||
} flash_file_t;
|
||||
|
||||
int flash_load(flash_file_t *ctx, const char *name, int can_write_bl);
|
||||
int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_size);
|
||||
int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t *chipid);
|
||||
int flash_write(flash_file_t *ctx);
|
||||
void flash_free(flash_file_t *ctx);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "ui.h"
|
||||
|
||||
#define MAX_FILES 4
|
||||
#define ONE_KB 1024
|
||||
|
||||
static void usage(char *argv0) {
|
||||
PrintAndLogEx(NORMAL, "Usage: %s <port> [-b] image.elf [image.elf...]\n", argv0);
|
||||
|
@ -76,6 +77,7 @@ int main(int argc, char **argv) {
|
|||
int num_files = 0;
|
||||
int res;
|
||||
flash_file_t files[MAX_FILES];
|
||||
char * filenames[MAX_FILES];
|
||||
|
||||
memset(files, 0, sizeof(files));
|
||||
|
||||
|
@ -102,11 +104,7 @@ int main(int argc, char **argv) {
|
|||
return -1;
|
||||
}
|
||||
} else {
|
||||
res = flash_load(&files[num_files], argv[i], can_write_bl);
|
||||
if (res < 0)
|
||||
return -1;
|
||||
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
filenames[num_files] = argv[i];
|
||||
num_files++;
|
||||
}
|
||||
}
|
||||
|
@ -132,9 +130,19 @@ int main(int argc, char **argv) {
|
|||
PrintAndLogEx(NORMAL, "Available memory on this board: "_RED_("UNKNOWN")"\n");
|
||||
PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new CHIP_INFO command"));
|
||||
PrintAndLogEx(ERR, _RED_("It is recommended that you update your bootloader") "\n");
|
||||
mem_avail = 256; //we default to a low value
|
||||
}
|
||||
|
||||
for (int i = 0 ; i < num_files; ++i){
|
||||
res = flash_load(&files[i], filenames[i], can_write_bl, mem_avail*ONE_KB);
|
||||
if (res < 0)
|
||||
return -1;
|
||||
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
}
|
||||
|
||||
PrintAndLogEx(SUCCESS, "\n" _BLUE_("Flashing..."));
|
||||
// TODO check if enough space on Pm3 mem to write the given files
|
||||
|
||||
for (int i = 0; i < num_files; i++) {
|
||||
res = flash_write(&files[i]);
|
||||
if (res < 0)
|
||||
|
|
Loading…
Reference in a new issue