diff options
author | Daniel Dickinson <crazycshore@gmail.com> | 2010-12-26 04:17:51 +0000 |
---|---|---|
committer | Daniel Dickinson <crazycshore@gmail.com> | 2010-12-26 04:17:51 +0000 |
commit | b1362f94bcc99a2190b0d6778c41e8a21d21aa02 (patch) | |
tree | 7faaeecd38876b420175913434ab15e163fee300 /package/mtd/src/trx.c | |
parent | ec45087403e899842bfc79a9e164e2403b815678 (diff) | |
download | upstream-b1362f94bcc99a2190b0d6778c41e8a21d21aa02.tar.gz upstream-b1362f94bcc99a2190b0d6778c41e8a21d21aa02.tar.bz2 upstream-b1362f94bcc99a2190b0d6778c41e8a21d21aa02.zip |
mtd: Changed mtd_fixtrx and related functions to be weak references. The weak references only lead to actual functions for brcm47xx
Signed-off-by: Daniel Dickinson <daniel@cshore.neomailbox.net>
SVN-Revision: 24833
Diffstat (limited to 'package/mtd/src/trx.c')
-rw-r--r-- | package/mtd/src/trx.c | 98 |
1 files changed, 93 insertions, 5 deletions
diff --git a/package/mtd/src/trx.c b/package/mtd/src/trx.c index 7094ef62b0..b8d9e2bf05 100644 --- a/package/mtd/src/trx.c +++ b/package/mtd/src/trx.c @@ -27,6 +27,7 @@ #include <sys/mman.h> #include <sys/stat.h> #include <string.h> +#include <errno.h> #include <sys/ioctl.h> #include "mtd-api.h" @@ -35,13 +36,24 @@ #define TRX_MAGIC 0x30524448 /* "HDR0" */ struct trx_header { - unsigned magic; /* "HDR0" */ - unsigned len; /* Length of file including header */ - unsigned crc32; /* 32-bit CRC from flag_version to end of file */ - unsigned flag_version; /* 0:15 flags, 16:31 version */ - unsigned offsets[3]; /* Offsets of partitions from start of header */ + uint32_t magic; /* "HDR0" */ + uint32_t len; /* Length of file including header */ + uint32_t crc32; /* 32-bit CRC from flag_version to end of file */ + uint32_t flag_version; /* 0:15 flags, 16:31 version */ + uint32_t offsets[3]; /* Offsets of partitions from start of header */ }; +#if __BYTE_ORDER == __BIG_ENDIAN +#define STORE32_LE(X) ((((X) & 0x000000FF) << 24) | (((X) & 0x0000FF00) << 8) | (((X) & 0x00FF0000) >> 8) | (((X) & 0xFF000000) >> 24)) +#elif __BYTE_ORDER == __LITTLE_ENDIAN +#define STORE32_LE(X) (X) +#else +#error unknown endianness! +#endif + +ssize_t pread(int fd, void *buf, size_t count, off_t offset); +ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset); + int trx_fixup(int fd, const char *name) { @@ -130,3 +142,79 @@ trx_check(int imagefd, const char *mtd, char *buf, int *len) return 1; } +int +mtd_fixtrx(const char *mtd, size_t offset) +{ + int fd; + struct trx_header *trx; + char *buf; + ssize_t res; + size_t block_offset; + + if (quiet < 2) + fprintf(stderr, "Trying to fix trx header in %s at 0x%x...\n", mtd, offset); + + block_offset = offset & ~(erasesize - 1); + offset -= block_offset; + + fd = mtd_check_open(mtd); + if(fd < 0) { + fprintf(stderr, "Could not open mtd device: %s\n", mtd); + exit(1); + } + + if (block_offset + erasesize > mtdsize) { + fprintf(stderr, "Offset too large, device size 0x%x\n", mtdsize); + exit(1); + } + + buf = malloc(erasesize); + if (!buf) { + perror("malloc"); + exit(1); + } + + res = pread(fd, buf, erasesize, block_offset); + if (res != erasesize) { + perror("pread"); + exit(1); + } + + trx = (struct trx_header *) (buf + offset); + if (trx->magic != STORE32_LE(0x30524448)) { + fprintf(stderr, "No trx magic found\n"); + exit(1); + } + + if (trx->len == STORE32_LE(erasesize - offset)) { + if (quiet < 2) + fprintf(stderr, "Header already fixed, exiting\n"); + close(fd); + return 0; + } + + trx->len = STORE32_LE(erasesize - offset); + + trx->crc32 = STORE32_LE(crc32buf((char*) &trx->flag_version, erasesize - offset - 3*4)); + if (mtd_erase_block(fd, block_offset)) { + fprintf(stderr, "Can't erease block at 0x%x (%s)\n", block_offset, strerror(errno)); + exit(1); + } + + if (quiet < 2) + fprintf(stderr, "New crc32: 0x%x, rewriting block\n", trx->crc32); + + if (pwrite(fd, buf, erasesize, block_offset) != erasesize) { + fprintf(stderr, "Error writing block (%s)\n", strerror(errno)); + exit(1); + } + + if (quiet < 2) + fprintf(stderr, "Done.\n"); + + close (fd); + sync(); + return 0; + +} + |