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
This commit is contained in:
Daniel Dickinson
2010-12-26 04:17:51 +00:00
parent ec45087403
commit b1362f94bc
3 changed files with 120 additions and 115 deletions

View File

@@ -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;
}