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:
		@@ -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) {
 | 
			
		||||
 | 
			
		||||
	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;
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
 | 
			
		||||
#ifdef target_brcm47xx
 | 
			
		||||
#if defined(target_brcm47xx) || defined(target_bcm53xx)
 | 
			
		||||
#define target_brcm 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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,15 +112,13 @@ 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) {
 | 
			
		||||
		*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) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user