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
This commit is contained in:
parent
18bcbbfd45
commit
b5c41ad28c
3 changed files with 60 additions and 13 deletions
|
@ -22,6 +22,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
|
#include <byteswap.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -50,8 +51,32 @@
|
||||||
#define MAX_ARGS 8
|
#define MAX_ARGS 8
|
||||||
#define JFFS2_DEFAULT_DIR "" /* directory name without /, empty means root dir */
|
#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 *buf = NULL;
|
||||||
static char *imagefile = NULL;
|
static char *imagefile = NULL;
|
||||||
|
static enum mtd_image_format imageformat = MTD_IMAGE_FORMAT_UNKNOWN;
|
||||||
static char *jffs2file = NULL, *jffs2dir = JFFS2_DEFAULT_DIR;
|
static char *jffs2file = NULL, *jffs2dir = JFFS2_DEFAULT_DIR;
|
||||||
static int buflen = 0;
|
static int buflen = 0;
|
||||||
int quiet;
|
int quiet;
|
||||||
|
@ -149,13 +174,39 @@ int mtd_write_buffer(int fd, const char *buf, int offset, int length)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
image_check(int imagefd, const char *mtd)
|
image_check(int imagefd, const char *mtd)
|
||||||
{
|
{
|
||||||
|
uint32_t magic;
|
||||||
int ret = 1;
|
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;
|
return ret;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#ifdef target_brcm47xx
|
#if defined(target_brcm47xx) || defined(target_bcm53xx)
|
||||||
#define target_brcm 1
|
#define target_brcm 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -44,8 +44,6 @@ struct trx_header {
|
||||||
uint32_t offsets[3]; /* Offsets of partitions from start of header */
|
uint32_t offsets[3]; /* Offsets of partitions from start of header */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SEAMA_MAGIC 0x17a4a35e
|
|
||||||
|
|
||||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||||
#define STORE32_LE(X) ((((X) & 0x000000FF) << 24) | (((X) & 0x0000FF00) << 8) | (((X) & 0x00FF0000) >> 8) | (((X) & 0xFF000000) >> 24))
|
#define STORE32_LE(X) ((((X) & 0x000000FF) << 24) | (((X) & 0x0000FF00) << 8) | (((X) & 0x00FF0000) >> 8) | (((X) & 0xFF000000) >> 24))
|
||||||
#elif __BYTE_ORDER == __LITTLE_ENDIAN
|
#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)
|
if (strcmp(mtd, "firmware") != 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
*len = read(imagefd, buf, 32);
|
|
||||||
if (*len < 32) {
|
if (*len < 32) {
|
||||||
fprintf(stdout, "Could not get image header, file too small (%d bytes)\n", *len);
|
*len += read(imagefd, buf + *len, 32 - *len);
|
||||||
return 0;
|
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 (trx->magic != TRX_MAGIC || trx->len < sizeof(struct trx_header)) {
|
||||||
if (quiet < 2) {
|
if (quiet < 2) {
|
||||||
fprintf(stderr, "Bad trx header\n");
|
fprintf(stderr, "Bad trx header\n");
|
||||||
|
|
Loading…
Reference in a new issue