1 //----------------------------------------------------------------------------- 
   2 // Copyright (C) 2010 Hector Martin "marcan" <marcan@marcansoft.com> 
   4 // This code is licensed to you under the terms of the GNU GPL, version 2 or, 
   5 // at your option, any later version. See the LICENSE.txt file for the text of 
   7 //----------------------------------------------------------------------------- 
   9 //----------------------------------------------------------------------------- 
  16 #include "proxmark3.h" 
  18 #include "util_posix.h" 
  21 #include "proxendian.h" 
  25 #define FLASH_START            0x100000 
  26 #define FLASH_SIZE             (256*1024) 
  27 #define FLASH_END              (FLASH_START + FLASH_SIZE) 
  28 #define BOOTLOADER_SIZE        0x2000 
  29 #define BOOTLOADER_END         (FLASH_START + BOOTLOADER_SIZE) 
  31 #define BLOCK_SIZE             0x200 
  33 static const uint8_t elf_ident
[] = { 
  41 // Turn PHDRs into flasher segments, checking for PHDR sanity and merging adjacent 
  42 // unaligned segments if needed 
  43 static int build_segs_from_phdrs(flash_file_t 
*ctx
, FILE *fd
, Elf32_Phdr 
*phdrs
, uint16_t num_phdrs
) 
  45         Elf32_Phdr 
*phdr 
= phdrs
; 
  47         uint32_t last_end 
= 0; 
  49         ctx
->segments 
= malloc(sizeof(flash_seg_t
) * num_phdrs
); 
  51                 fprintf(stderr
, "Out of memory\n"); 
  57         fprintf(stderr
, "Loading usable ELF segments:\n"); 
  58         for (int i 
= 0; i 
< num_phdrs
; i
++) { 
  59                 if (le32(phdr
->p_type
) != PT_LOAD
) { 
  63                 uint32_t vaddr 
= le32(phdr
->p_vaddr
); 
  64                 uint32_t paddr 
= le32(phdr
->p_paddr
); 
  65                 uint32_t filesz 
= le32(phdr
->p_filesz
); 
  66                 uint32_t memsz 
= le32(phdr
->p_memsz
); 
  67                 uint32_t offset 
= le32(phdr
->p_offset
); 
  68                 uint32_t flags 
= le32(phdr
->p_flags
); 
  73                 fprintf(stderr
, "%d: V 0x%08x P 0x%08x (0x%08x->0x%08x) [%c%c%c] @0x%x\n", 
  74                         i
, vaddr
, paddr
, filesz
, memsz
, 
  75                         flags 
& PF_R 
? 'R' : ' ', 
  76                         flags 
& PF_W 
? 'W' : ' ', 
  77                         flags 
& PF_X 
? 'X' : ' ', 
  79                 if (filesz 
!= memsz
) { 
  80                         fprintf(stderr
, "Error: PHDR file size does not equal memory size\n" 
  81                                         "(DATA+BSS PHDRs do not make sense on ROM platforms!)\n"); 
  84                 if (paddr 
< last_end
) { 
  85                         fprintf(stderr
, "Error: PHDRs not sorted or overlap\n"); 
  88                 if (paddr 
< FLASH_START 
|| (paddr
+filesz
) > FLASH_END
) { 
  89                         fprintf(stderr
, "Error: PHDR is not contained in Flash\n"); 
  92                 if (vaddr 
>= FLASH_START 
&& vaddr 
< FLASH_END 
&& (flags 
& PF_W
)) { 
  93                         fprintf(stderr
, "Error: Flash VMA segment is writable\n"); 
  98                 // make extra space if we need to move the data forward 
  99                 data 
= malloc(filesz 
+ BLOCK_SIZE
); 
 101                         fprintf(stderr
, "Out of memory\n"); 
 104                 if (fseek(fd
, offset
, SEEK_SET
) < 0 || fread(data
, 1, filesz
, fd
) != filesz
) { 
 105                         fprintf(stderr
, "Error while reading PHDR payload\n"); 
 110                 uint32_t block_offset 
= paddr 
& (BLOCK_SIZE
-1); 
 113                                 flash_seg_t 
*prev_seg 
= seg 
- 1; 
 114                                 uint32_t this_end 
= paddr 
+ filesz
; 
 115                                 uint32_t this_firstblock 
= paddr 
& ~(BLOCK_SIZE
-1); 
 116                                 uint32_t prev_lastblock 
= (last_end 
- 1) & ~(BLOCK_SIZE
-1); 
 118                                 if (this_firstblock 
== prev_lastblock
) { 
 119                                         uint32_t new_length 
= this_end 
- prev_seg
->start
; 
 120                                         uint32_t this_offset 
= paddr 
- prev_seg
->start
; 
 121                                         uint32_t hole 
= this_offset 
- prev_seg
->length
; 
 122                                         uint8_t *new_data 
= malloc(new_length
); 
 124                                                 fprintf(stderr
, "Out of memory\n"); 
 128                                         memset(new_data
, 0xff, new_length
); 
 129                                         memcpy(new_data
, prev_seg
->data
, prev_seg
->length
); 
 130                                         memcpy(new_data 
+ this_offset
, data
, filesz
); 
 131                                         fprintf(stderr
, "Note: Extending previous segment from 0x%x to 0x%x bytes\n", 
 132                                                 prev_seg
->length
, new_length
); 
 134                                                 fprintf(stderr
, "Note: 0x%x-byte hole created\n", hole
); 
 136                                         free(prev_seg
->data
); 
 137                                         prev_seg
->data 
= new_data
; 
 138                                         prev_seg
->length 
= new_length
; 
 144                         fprintf(stderr
, "Warning: segment does not begin on a block boundary, will pad\n"); 
 145                         memmove(data 
+ block_offset
, data
, filesz
); 
 146                         memset(data
, 0xFF, block_offset
); 
 147                         filesz 
+= block_offset
; 
 148                         paddr 
-= block_offset
; 
 153                 seg
->length 
= filesz
; 
 157                 last_end 
= paddr 
+ filesz
; 
 163 // Sanity check segments and check for bootloader writes 
 164 static int check_segs(flash_file_t 
*ctx
, int can_write_bl
) { 
 165         for (int i 
= 0; i 
< ctx
->num_segs
; i
++) { 
 166                 flash_seg_t 
*seg 
= &ctx
->segments
[i
]; 
 168                 if (seg
->start 
& (BLOCK_SIZE
-1)) { 
 169                         fprintf(stderr
, "Error: Segment is not aligned\n"); 
 172                 if (seg
->start 
< FLASH_START
) { 
 173                         fprintf(stderr
, "Error: Segment is outside of flash bounds\n"); 
 176                 if (seg
->start 
+ seg
->length 
> FLASH_END
) { 
 177                         fprintf(stderr
, "Error: Segment is outside of flash bounds\n"); 
 180                 if (!can_write_bl 
&& seg
->start 
< BOOTLOADER_END
) { 
 181                         fprintf(stderr
, "Attempted to write bootloader but bootloader writes are not enabled\n"); 
 188 // Load an ELF file and prepare it for flashing 
 189 int flash_load(flash_file_t 
*ctx
, const char *name
, bool can_write_bl
) 
 193         Elf32_Phdr 
*phdrs 
= NULL
; 
 197         fd 
= fopen(name
, "rb"); 
 199                 fprintf(stderr
, "Could not open file '%s': ", name
); 
 204         fprintf(stderr
, "Loading ELF file '%s'...\n", name
); 
 206         if (fread(&ehdr
, sizeof(ehdr
), 1, fd
) != 1) { 
 207                 fprintf(stderr
, "Error while reading ELF file header\n"); 
 210         if (memcmp(ehdr
.e_ident
, elf_ident
, sizeof(elf_ident
)) 
 211                 || le32(ehdr
.e_version
) != 1) 
 213                 fprintf(stderr
, "Not an ELF file or wrong ELF type\n"); 
 216         if (le16(ehdr
.e_type
) != ET_EXEC
) { 
 217                 fprintf(stderr
, "ELF is not executable\n"); 
 220         if (le16(ehdr
.e_machine
) != EM_ARM
) { 
 221                 fprintf(stderr
, "Wrong ELF architecture\n"); 
 224         if (!ehdr
.e_phnum 
|| !ehdr
.e_phoff
) { 
 225                 fprintf(stderr
, "ELF has no PHDRs\n"); 
 228         if (le16(ehdr
.e_phentsize
) != sizeof(Elf32_Phdr
)) { 
 229                 // could be a structure padding issue... 
 230                 fprintf(stderr
, "Either the ELF file or this code is made of fail\n"); 
 233         num_phdrs 
= le16(ehdr
.e_phnum
); 
 235         phdrs 
= malloc(le16(ehdr
.e_phnum
) * sizeof(Elf32_Phdr
)); 
 237                 fprintf(stderr
, "Out of memory\n"); 
 240         if (fseek(fd
, le32(ehdr
.e_phoff
), SEEK_SET
) < 0) { 
 241                 fprintf(stderr
, "Error while reading ELF PHDRs\n"); 
 244         if (fread(phdrs
, sizeof(Elf32_Phdr
), num_phdrs
, fd
) != num_phdrs
) { 
 245                 fprintf(stderr
, "Error while reading ELF PHDRs\n"); 
 249         res 
= build_segs_from_phdrs(ctx
, fd
, phdrs
, num_phdrs
); 
 252         res 
= check_segs(ctx
, can_write_bl
); 
 258         ctx
->filename 
= name
; 
 270 // Get the state of the proxmark, backwards compatible 
 271 static int get_proxmark_state(uint32_t *state
) 
 274         c
.cmd 
= CMD_DEVICE_INFO
; 
 277         WaitForResponse(CMD_UNKNOWN
, &resp
);  // wait for any response. No timeout. 
 280         // 1. The old bootrom code will ignore CMD_DEVICE_INFO, but respond with an ACK 
 281         // 2. The old os code will respond with CMD_DEBUG_PRINT_STRING and "unknown command" 
 282         // 3. The new bootrom and os codes will respond with CMD_DEVICE_INFO and flags 
 286                         *state 
= DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM
; 
 288                 case CMD_DEBUG_PRINT_STRING
: 
 289                         *state 
= DEVICE_INFO_FLAG_CURRENT_MODE_OS
; 
 291                 case CMD_DEVICE_INFO
: 
 292                         *state 
= resp
.arg
[0]; 
 295                         fprintf(stderr
, "Error: Couldn't get proxmark state, bad response type: 0x%04" PRIx64 
"\n", resp
.cmd
); 
 303 // Enter the bootloader to be able to start flashing 
 304 static int enter_bootloader(char *serial_port_name
) 
 308         if (get_proxmark_state(&state
) < 0) 
 311         if (state 
& DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM
) { 
 312                 /* Already in flash state, we're done. */ 
 316         if (state 
& DEVICE_INFO_FLAG_CURRENT_MODE_OS
) { 
 317                 fprintf(stderr
,"Entering bootloader...\n"); 
 319                 memset(&c
, 0, sizeof (c
)); 
 321                 if ((state 
& DEVICE_INFO_FLAG_BOOTROM_PRESENT
) 
 322                         && (state 
& DEVICE_INFO_FLAG_OSIMAGE_PRESENT
)) 
 324                         // New style handover: Send CMD_START_FLASH, which will reset the board 
 325                         // and enter the bootrom on the next boot. 
 326                         c
.cmd 
= CMD_START_FLASH
; 
 328                         fprintf(stderr
,"(Press and release the button only to abort)\n"); 
 330                         // Old style handover: Ask the user to press the button, then reset the board 
 331                         c
.cmd 
= CMD_HARDWARE_RESET
; 
 333                         fprintf(stderr
,"Press and hold down button NOW if your bootloader requires it.\n"); 
 339                 bool opened 
= OpenProxmark(serial_port_name
, true, 120, true);   // wait for 2 minutes 
 341                         fprintf(stderr
," Found.\n"); 
 344                         fprintf(stderr
,"Error: Proxmark not found.\n"); 
 349         fprintf(stderr
, "Error: Unknown Proxmark mode\n"); 
 353 static int wait_for_ack(void) 
 356         WaitForResponse(CMD_UNKNOWN
, &ack
); 
 357         if (ack
.cmd 
!= CMD_ACK
) { 
 358                 printf("Error: Unexpected reply 0x%04" PRIx64 
" (expected ACK)\n", ack
.cmd
); 
 364 // Go into flashing mode 
 365 int flash_start_flashing(int enable_bl_writes
,char *serial_port_name
) 
 369         if (enter_bootloader(serial_port_name
) < 0) 
 372         if (get_proxmark_state(&state
) < 0) 
 375         if (state 
& DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH
) { 
 376                 // This command is stupid. Why the heck does it care which area we're 
 377                 // flashing, as long as it's not the bootloader area? The mind boggles. 
 378                 UsbCommand c 
= {CMD_START_FLASH
}; 
 380                 if (enable_bl_writes
) { 
 381                         c
.arg
[0] = FLASH_START
; 
 382                         c
.arg
[1] = FLASH_END
; 
 383                         c
.arg
[2] = START_FLASH_MAGIC
; 
 385                         c
.arg
[0] = BOOTLOADER_END
; 
 386                         c
.arg
[1] = FLASH_END
; 
 390                 return wait_for_ack(); 
 392                 fprintf(stderr
, "Note: Your bootloader does not understand the new START_FLASH command\n"); 
 393                 fprintf(stderr
, "      It is recommended that you update your bootloader\n\n"); 
 399 static int write_block(uint32_t address
, uint8_t *data
, uint32_t length
) 
 401         uint8_t block_buf
[BLOCK_SIZE
]; 
 403         memset(block_buf
, 0xFF, BLOCK_SIZE
); 
 404         memcpy(block_buf
, data
, length
); 
 406         c
.cmd 
= CMD_FINISH_WRITE
; 
 408         memcpy(c
.d
.asBytes
, block_buf
, length
); 
 410         return wait_for_ack(); 
 413 // Write a file's segments to Flash 
 414 int flash_write(flash_file_t 
*ctx
) 
 416         fprintf(stderr
, "Writing segments for file: %s\n", ctx
->filename
); 
 417         for (int i 
= 0; i 
< ctx
->num_segs
; i
++) { 
 418                 flash_seg_t 
*seg 
= &ctx
->segments
[i
]; 
 420                 uint32_t length 
= seg
->length
; 
 421                 uint32_t blocks 
= (length 
+ BLOCK_SIZE 
- 1) / BLOCK_SIZE
; 
 422                 uint32_t end 
= seg
->start 
+ length
; 
 424                 fprintf(stderr
, " 0x%08x..0x%08x [0x%x / %d blocks]", 
 425                         seg
->start
, end 
- 1, length
, blocks
); 
 428                 uint8_t *data 
= seg
->data
; 
 429                 uint32_t baddr 
= seg
->start
; 
 432                         uint32_t block_size 
= length
; 
 433                         if (block_size 
> BLOCK_SIZE
) 
 434                                 block_size 
= BLOCK_SIZE
; 
 436                         if (write_block(baddr
, data
, block_size
) < 0) { 
 437                                 fprintf(stderr
, " ERROR\n"); 
 438                                 fprintf(stderr
, "Error writing block %d of %d\n", block
, blocks
); 
 444                         length 
-= block_size
; 
 446                         fprintf(stderr
, "."); 
 448                 fprintf(stderr
, " OK\n"); 
 453 // free a file context 
 454 void flash_free(flash_file_t 
*ctx
) 
 459                 for (int i 
= 0; i 
< ctx
->num_segs
; i
++) 
 460                         free(ctx
->segments
[i
].data
); 
 462                 ctx
->segments 
= NULL
; 
 467 // just reset the unit 
 468 int flash_stop_flashing(void) { 
 469         UsbCommand c 
= {CMD_HARDWARE_RESET
};