diff options
author | Rafał Miłecki <zajec5@gmail.com> | 2016-02-06 16:29:12 +0000 |
---|---|---|
committer | Rafał Miłecki <zajec5@gmail.com> | 2016-02-06 16:29:12 +0000 |
commit | b5c41ad28c31d61d6eb9a0c0f3550e75ea74e09f (patch) | |
tree | 4a27986c99e9dee059bf4ceeb83349dcf4fa7e59 /package/system/mtd/src/mtd.c | |
parent | 18bcbbfd457462d92bbb0a1854d468834c131f51 (diff) | |
download | upstream-b5c41ad28c31d61d6eb9a0c0f3550e75ea74e09f.tar.gz upstream-b5c41ad28c31d61d6eb9a0c0f3550e75ea74e09f.tar.bz2 upstream-b5c41ad28c31d61d6eb9a0c0f3550e75ea74e09f.zip |
mtd: detect image format when writing
Recently TRX checking code was changed to detect Seama format and don't
abort whole writing operation because of it. This isn't a good long-term
solution. It's a poor idea to teach every format handler recognizing all
possible formats. Instead it should be handled in a generic code which
should run check depending on the detected format.
This will also allow further improvements like fixing formats other than
TRX after replacing JFFS2.
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
SVN-Revision: 48639
Diffstat (limited to 'package/system/mtd/src/mtd.c')
-rw-r--r-- | package/system/mtd/src/mtd.c | 57 |
1 files changed, 54 insertions, 3 deletions
diff --git a/package/system/mtd/src/mtd.c b/package/system/mtd/src/mtd.c index 02476306f6..03ee5671d5 100644 --- a/package/system/mtd/src/mtd.c +++ b/package/system/mtd/src/mtd.c @@ -22,6 +22,7 @@ */ #define _GNU_SOURCE +#include <byteswap.h> #include <limits.h> #include <unistd.h> #include <stdlib.h> @@ -50,8 +51,32 @@ #define MAX_ARGS 8 #define JFFS2_DEFAULT_DIR "" /* directory name without /, empty means root dir */ +#define TRX_MAGIC 0x48445230 /* "HDR0" */ +#define SEAMA_MAGIC 0x5ea3a417 + +#if !defined(__BYTE_ORDER) +#error "Unknown byte order" +#endif + +#if __BYTE_ORDER == __BIG_ENDIAN +#define cpu_to_be32(x) (x) +#define be32_to_cpu(x) (x) +#elif __BYTE_ORDER == __LITTLE_ENDIAN +#define cpu_to_be32(x) bswap_32(x) +#define be32_to_cpu(x) bswap_32(x) +#else +#error "Unsupported endianness" +#endif + +enum mtd_image_format { + MTD_IMAGE_FORMAT_UNKNOWN, + MTD_IMAGE_FORMAT_TRX, + MTD_IMAGE_FORMAT_SEAMA, +}; + static char *buf = NULL; static char *imagefile = NULL; +static enum mtd_image_format imageformat = MTD_IMAGE_FORMAT_UNKNOWN; static char *jffs2file = NULL, *jffs2dir = JFFS2_DEFAULT_DIR; static int buflen = 0; int quiet; @@ -149,13 +174,39 @@ int mtd_write_buffer(int fd, const char *buf, int offset, int length) return 0; } - static int image_check(int imagefd, const char *mtd) { + uint32_t magic; int ret = 1; - if (trx_check) { - ret = trx_check(imagefd, mtd, buf, &buflen); + + if (buflen < sizeof(magic)) { + buflen += read(imagefd, buf + buflen, sizeof(magic) - buflen); + if (buflen < sizeof(magic)) { + fprintf(stdout, "Could not get image magic\n"); + return 0; + } + } + magic = ((uint32_t *)buf)[0]; + + if (be32_to_cpu(magic) == TRX_MAGIC) + imageformat = MTD_IMAGE_FORMAT_TRX; + else if (be32_to_cpu(magic) == SEAMA_MAGIC) + imageformat = MTD_IMAGE_FORMAT_SEAMA; + + switch (imageformat) { + case MTD_IMAGE_FORMAT_TRX: + if (trx_check) + ret = trx_check(imagefd, mtd, buf, &buflen); + break; + case MTD_IMAGE_FORMAT_SEAMA: + break; + default: +#ifdef target_brcm + if (!strcmp(mtd, "firmware")) + ret = 0; +#endif + break; } return ret; |