mirror of
https://gitea.osmocom.org/sim-card/simtrace2.git
synced 2026-03-16 21:28:33 +03:00
DFU flashing of apps sometimes aborts, and although rare this leads to broken devices if no boot button or serial/jtag access exists, because the bootloader will keep trying to start a half-flashed app that then crashes at some point. The easiest fix that works with existing bootloaders is to prepend a small 512 byte stub that calculcates the crc and compares it with the crc calculated at build time, and then either starts the actual app, or sets the dfu flag and resets. This ensures we either have a working, running app, or end up in the bootloader, ready to flash again. For obvious reasons this only applies to dfu apps, and not to flash targets like the actual bootloader itself. Change-Id: Id6df0486c8b779889d21800dc2441b3aa9af8a5f
92 lines
2.2 KiB
C
92 lines
2.2 KiB
C
/* SIMtrace 2 firmware crc tool
|
|
*
|
|
* (C) 2021 by sysmocom -s.f.m.c. GmbH, Author: Eric Wild <ewild@sysmocom.de>
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
static void do_crc32(int8_t c, uint32_t *crc_reg)
|
|
{
|
|
int32_t i, mask;
|
|
*crc_reg ^= c;
|
|
|
|
for (unsigned int j = 0; j < 8; j++)
|
|
if (*crc_reg & 1)
|
|
*crc_reg = (*crc_reg >> 1) ^ 0xEDB88320;
|
|
else
|
|
*crc_reg = *crc_reg >> 1;
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
uint32_t crc_reg = 0xffffffff;
|
|
long fsize;
|
|
uint8_t *buffer;
|
|
uint32_t crc_start_offset;
|
|
|
|
if (argc < 3) {
|
|
perror("usage: crctool startoffset blupdate.bin");
|
|
return -1;
|
|
}
|
|
|
|
crc_start_offset = strtoull(argv[1], 0, 10);
|
|
|
|
FILE *blfile = fopen(argv[2], "rb+");
|
|
if (blfile == NULL) {
|
|
perror("error opening file!");
|
|
return -1;
|
|
}
|
|
|
|
fseek(blfile, 0, SEEK_END);
|
|
fsize = ftell(blfile);
|
|
|
|
if (fsize <= crc_start_offset) {
|
|
perror("file size?!");
|
|
return -1;
|
|
}
|
|
|
|
fseek(blfile, 0, SEEK_SET);
|
|
|
|
buffer = malloc(fsize);
|
|
fread(buffer, 1, fsize, blfile);
|
|
|
|
if (*(uint32_t *)buffer != 0xdeadc0de) {
|
|
perror("weird magic, not a valid blupdate file?");
|
|
free(buffer);
|
|
return -1;
|
|
}
|
|
|
|
uint8_t *startaddr = buffer + crc_start_offset;
|
|
uint8_t *endaddr = buffer + fsize;
|
|
for (uint8_t *i = startaddr; i < endaddr; i++) {
|
|
do_crc32(*i, &crc_reg);
|
|
}
|
|
crc_reg = ~crc_reg;
|
|
|
|
fprintf(stderr, "len: %ld crc: %.8x\n", fsize - crc_start_offset, crc_reg);
|
|
|
|
((uint32_t *)buffer)[0] = 0x2000baa0; /* fix magic to valid stack address, checked by BL */
|
|
((uint32_t *)buffer)[2] = crc_reg;
|
|
((uint32_t *)buffer)[3] = 0x00400000 + 0x4000 + crc_start_offset;
|
|
((uint32_t *)buffer)[4] = fsize - crc_start_offset;
|
|
|
|
fseek(blfile, 0, SEEK_SET);
|
|
fwrite(buffer, 4, 5, blfile);
|
|
|
|
fclose(blfile);
|
|
free(buffer);
|
|
return 0;
|
|
}
|