mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-20 06:08:08 +00:00
mtd: add -c option for specifying amount of data to be used for checksum
So far fixtrx was calculating checksum over amount of data matching partition erase size. It was mostly a workaround of checksum problem after changing anything in initial TRX content (e.g. formatting JFFS2). Its main purpose was to make bootloader accept modified TRX. This didn't provide much protection of flash data against corruption. This new option lets caller request calculating checksum over a bigger amount of data. It may be used e.g. to include whole kernel data for checksum and hopefully make bootloader go info failsafe mode if something goes wrong. Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
This commit is contained in:
parent
2dd125048d
commit
df8ca9a5c4
@ -737,6 +737,8 @@ static void usage(void)
|
|||||||
if (mtd_fixtrx) {
|
if (mtd_fixtrx) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
" -o offset offset of the image header in the partition(for fixtrx)\n");
|
" -o offset offset of the image header in the partition(for fixtrx)\n");
|
||||||
|
fprintf(stderr,
|
||||||
|
" -c datasize amount of data to be used for checksum calculation (for fixtrx)\n");
|
||||||
}
|
}
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
#ifdef FIS_SUPPORT
|
#ifdef FIS_SUPPORT
|
||||||
@ -769,7 +771,7 @@ int main (int argc, char **argv)
|
|||||||
int ch, i, boot, imagefd = 0, force, unlocked;
|
int ch, i, boot, imagefd = 0, force, unlocked;
|
||||||
char *erase[MAX_ARGS], *device = NULL;
|
char *erase[MAX_ARGS], *device = NULL;
|
||||||
char *fis_layout = NULL;
|
char *fis_layout = NULL;
|
||||||
size_t offset = 0, part_offset = 0, dump_len = 0;
|
size_t offset = 0, data_size = 0, part_offset = 0, dump_len = 0;
|
||||||
enum {
|
enum {
|
||||||
CMD_ERASE,
|
CMD_ERASE,
|
||||||
CMD_WRITE,
|
CMD_WRITE,
|
||||||
@ -793,7 +795,7 @@ int main (int argc, char **argv)
|
|||||||
#ifdef FIS_SUPPORT
|
#ifdef FIS_SUPPORT
|
||||||
"F:"
|
"F:"
|
||||||
#endif
|
#endif
|
||||||
"frnqe:d:s:j:p:o:l:")) != -1)
|
"frnqe:d:s:j:p:o:c:l:")) != -1)
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'f':
|
case 'f':
|
||||||
force = 1;
|
force = 1;
|
||||||
@ -853,6 +855,14 @@ int main (int argc, char **argv)
|
|||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'c':
|
||||||
|
errno = 0;
|
||||||
|
data_size = strtoul(optarg, 0, 0);
|
||||||
|
if (errno) {
|
||||||
|
fprintf(stderr, "-d: illegal numeric string\n");
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
break;
|
||||||
#ifdef FIS_SUPPORT
|
#ifdef FIS_SUPPORT
|
||||||
case 'F':
|
case 'F':
|
||||||
fis_layout = optarg;
|
fis_layout = optarg;
|
||||||
@ -967,7 +977,7 @@ int main (int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
case CMD_FIXTRX:
|
case CMD_FIXTRX:
|
||||||
if (mtd_fixtrx) {
|
if (mtd_fixtrx) {
|
||||||
mtd_fixtrx(device, offset);
|
mtd_fixtrx(device, offset, data_size);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CMD_RESETBC:
|
case CMD_RESETBC:
|
||||||
|
@ -25,7 +25,7 @@ extern void mtd_parse_jffs2data(const char *buf, const char *dir);
|
|||||||
/* target specific functions */
|
/* target specific functions */
|
||||||
extern int trx_fixup(int fd, const char *name) __attribute__ ((weak));
|
extern int trx_fixup(int fd, const char *name) __attribute__ ((weak));
|
||||||
extern int trx_check(int imagefd, const char *mtd, char *buf, int *len) __attribute__ ((weak));
|
extern int trx_check(int imagefd, const char *mtd, char *buf, int *len) __attribute__ ((weak));
|
||||||
extern int mtd_fixtrx(const char *mtd, size_t offset) __attribute__ ((weak));
|
extern int mtd_fixtrx(const char *mtd, size_t offset, size_t data_size) __attribute__ ((weak));
|
||||||
extern int mtd_fixseama(const char *mtd, size_t offset) __attribute__ ((weak));
|
extern int mtd_fixseama(const char *mtd, size_t offset) __attribute__ ((weak));
|
||||||
extern int mtd_resetbc(const char *mtd) __attribute__ ((weak));
|
extern int mtd_resetbc(const char *mtd) __attribute__ ((weak));
|
||||||
#endif /* __mtd_h */
|
#endif /* __mtd_h */
|
||||||
|
@ -36,6 +36,8 @@
|
|||||||
#include "crc32.h"
|
#include "crc32.h"
|
||||||
|
|
||||||
#define TRX_MAGIC 0x30524448 /* "HDR0" */
|
#define TRX_MAGIC 0x30524448 /* "HDR0" */
|
||||||
|
#define TRX_CRC32_DATA_OFFSET 12 /* First 12 bytes are not covered by CRC32 */
|
||||||
|
#define TRX_CRC32_DATA_SIZE 16
|
||||||
struct trx_header {
|
struct trx_header {
|
||||||
uint32_t magic; /* "HDR0" */
|
uint32_t magic; /* "HDR0" */
|
||||||
uint32_t len; /* Length of file including header */
|
uint32_t len; /* Length of file including header */
|
||||||
@ -148,8 +150,9 @@ trx_check(int imagefd, const char *mtd, char *buf, int *len)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
mtd_fixtrx(const char *mtd, size_t offset)
|
mtd_fixtrx(const char *mtd, size_t offset, size_t data_size)
|
||||||
{
|
{
|
||||||
|
size_t data_offset;
|
||||||
int fd;
|
int fd;
|
||||||
struct trx_header *trx;
|
struct trx_header *trx;
|
||||||
char *first_block;
|
char *first_block;
|
||||||
@ -166,10 +169,16 @@ mtd_fixtrx(const char *mtd, size_t offset)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data_offset = offset + TRX_CRC32_DATA_OFFSET;
|
||||||
|
if (data_size)
|
||||||
|
data_size += TRX_CRC32_DATA_SIZE;
|
||||||
|
else
|
||||||
|
data_size = erasesize - TRX_CRC32_DATA_OFFSET;
|
||||||
|
|
||||||
block_offset = offset & ~(erasesize - 1);
|
block_offset = offset & ~(erasesize - 1);
|
||||||
offset -= block_offset;
|
offset -= block_offset;
|
||||||
|
|
||||||
if (block_offset + erasesize > mtdsize) {
|
if (data_offset + data_size > mtdsize) {
|
||||||
fprintf(stderr, "Offset too large, device size 0x%x\n", mtdsize);
|
fprintf(stderr, "Offset too large, device size 0x%x\n", mtdsize);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@ -192,28 +201,28 @@ mtd_fixtrx(const char *mtd, size_t offset)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trx->len == STORE32_LE(erasesize - offset)) {
|
if (trx->len == STORE32_LE(data_size + TRX_CRC32_DATA_OFFSET)) {
|
||||||
if (quiet < 2)
|
if (quiet < 2)
|
||||||
fprintf(stderr, "Header already fixed, exiting\n");
|
fprintf(stderr, "Header already fixed, exiting\n");
|
||||||
close(fd);
|
close(fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = malloc(erasesize);
|
buf = malloc(data_size);
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
perror("malloc");
|
perror("malloc");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
res = pread(fd, buf, erasesize, block_offset);
|
res = pread(fd, buf, data_size, data_offset);
|
||||||
if (res != erasesize) {
|
if (res != data_size) {
|
||||||
perror("pread");
|
perror("pread");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
trx->len = STORE32_LE(erasesize - offset);
|
trx->len = STORE32_LE(data_size + offsetof(struct trx_header, flag_version));
|
||||||
|
|
||||||
trx->crc32 = STORE32_LE(crc32buf((char*) &trx->flag_version, erasesize - offset - 3*4));
|
trx->crc32 = STORE32_LE(crc32buf(buf, data_size));
|
||||||
if (mtd_erase_block(fd, block_offset)) {
|
if (mtd_erase_block(fd, block_offset)) {
|
||||||
fprintf(stderr, "Can't erease block at 0x%x (%s)\n", block_offset, strerror(errno));
|
fprintf(stderr, "Can't erease block at 0x%x (%s)\n", block_offset, strerror(errno));
|
||||||
exit(1);
|
exit(1);
|
||||||
|
Loading…
Reference in New Issue
Block a user