|
|
@@ -36,6 +36,8 @@
|
|
|
#include "crc32.h"
|
|
|
|
|
|
#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 {
|
|
|
uint32_t magic; /* "HDR0" */
|
|
|
uint32_t len; /* Length of file including header */
|
|
|
@@ -148,8 +150,9 @@ trx_check(int imagefd, const char *mtd, char *buf, int *len)
|
|
|
#endif
|
|
|
|
|
|
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;
|
|
|
struct trx_header *trx;
|
|
|
char *first_block;
|
|
|
@@ -166,10 +169,16 @@ mtd_fixtrx(const char *mtd, size_t offset)
|
|
|
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);
|
|
|
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);
|
|
|
exit(1);
|
|
|
}
|
|
|
@@ -192,28 +201,28 @@ mtd_fixtrx(const char *mtd, size_t offset)
|
|
|
exit(1);
|
|
|
}
|
|
|
|
|
|
- if (trx->len == STORE32_LE(erasesize - offset)) {
|
|
|
+ if (trx->len == STORE32_LE(data_size + TRX_CRC32_DATA_OFFSET)) {
|
|
|
if (quiet < 2)
|
|
|
fprintf(stderr, "Header already fixed, exiting\n");
|
|
|
close(fd);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- buf = malloc(erasesize);
|
|
|
+ buf = malloc(data_size);
|
|
|
if (!buf) {
|
|
|
perror("malloc");
|
|
|
exit(1);
|
|
|
}
|
|
|
|
|
|
- res = pread(fd, buf, erasesize, block_offset);
|
|
|
- if (res != erasesize) {
|
|
|
+ res = pread(fd, buf, data_size, data_offset);
|
|
|
+ if (res != data_size) {
|
|
|
perror("pread");
|
|
|
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)) {
|
|
|
fprintf(stderr, "Can't erease block at 0x%x (%s)\n", block_offset, strerror(errno));
|
|
|
exit(1);
|