aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--package/system/mtd/src/mtd.c57
-rw-r--r--package/system/mtd/src/mtd.h2
-rw-r--r--package/system/mtd/src/trx.c14
3 files changed, 60 insertions, 13 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;
diff --git a/package/system/mtd/src/mtd.h b/package/system/mtd/src/mtd.h
index fb37b8b9fa..751b0d09f6 100644
--- a/package/system/mtd/src/mtd.h
+++ b/package/system/mtd/src/mtd.h
@@ -3,7 +3,7 @@
#include <stdbool.h>
-#ifdef target_brcm47xx
+#if defined(target_brcm47xx) || defined(target_bcm53xx)
#define target_brcm 1
#endif
diff --git a/package/system/mtd/src/trx.c b/package/system/mtd/src/trx.c
index 5763917827..00c4d6c0b5 100644
--- a/package/system/mtd/src/trx.c
+++ b/package/system/mtd/src/trx.c
@@ -44,8 +44,6 @@ struct trx_header {
uint32_t offsets[3]; /* Offsets of partitions from start of header */
};
-#define SEAMA_MAGIC 0x17a4a35e
-
#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
@@ -114,16 +112,14 @@ trx_check(int imagefd, const char *mtd, char *buf, int *len)
if (strcmp(mtd, "firmware") != 0)
return 1;
- *len = read(imagefd, buf, 32);
if (*len < 32) {
- fprintf(stdout, "Could not get image header, file too small (%d bytes)\n", *len);
- return 0;
+ *len += read(imagefd, buf + *len, 32 - *len);
+ if (*len < 32) {
+ fprintf(stdout, "Could not get image header, file too small (%d bytes)\n", *len);
+ return 0;
+ }
}
- /* Allow writing Seama files to firmware without an extra validation */
- if (trx->magic == SEAMA_MAGIC)
- return 1;
-
if (trx->magic != TRX_MAGIC || trx->len < sizeof(struct trx_header)) {
if (quiet < 2) {
fprintf(stderr, "Bad trx header\n");