X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=package%2Fsystem%2Fmtd%2Fsrc%2Fmtd.c;h=60ae7adcdfac56541deb6a460175679a91baaffa;hb=8a60a419512db35f4d3583589e0e623a1a2f00c9;hp=741b57b48070d28d093fa5fc843d0ca84b3eb3b7;hpb=b48b7a7689b15754938c77449d59c16fc3765b1f;p=librecmc%2Flibrecmc.git diff --git a/package/system/mtd/src/mtd.c b/package/system/mtd/src/mtd.c index 741b57b480..60ae7adcdf 100644 --- a/package/system/mtd/src/mtd.c +++ b/package/system/mtd/src/mtd.c @@ -22,6 +22,7 @@ */ #define _GNU_SOURCE +#include #include #include #include @@ -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,46 @@ 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); + int bufread; + + while (buflen < sizeof(magic)) { + bufread = read(imagefd, buf + buflen, sizeof(magic) - buflen); + if (bufread < 1) + break; + + buflen += bufread; + } + + 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; @@ -608,8 +666,19 @@ resume: offset = 0; } - if (jffs2_replaced && trx_fixup) { - trx_fixup(fd, mtd); + if (jffs2_replaced) { + switch (imageformat) { + case MTD_IMAGE_FORMAT_TRX: + if (trx_fixup) + trx_fixup(fd, mtd); + break; + case MTD_IMAGE_FORMAT_SEAMA: + if (mtd_fixseama) + mtd_fixseama(mtd, 0); + break; + default: + break; + } } if (!quiet) @@ -640,6 +709,10 @@ static void usage(void) " verify |- verify (use - for stdin) to device\n" " write |- write (use - for stdin) to device\n" " jffs2write append to the jffs2 partition on the device\n"); + if (mtd_resetbc) { + fprintf(stderr, + " resetbc reset the uboot boot counter\n"); + } if (mtd_fixtrx) { fprintf(stderr, " fixtrx fix the checksum in a trx header on first boot\n"); @@ -706,6 +779,7 @@ int main (int argc, char **argv) CMD_FIXSEAMA, CMD_VERIFY, CMD_DUMP, + CMD_RESETBC, } cmd = -1; erase[0] = NULL; @@ -800,6 +874,9 @@ int main (int argc, char **argv) } else if ((strcmp(argv[0], "erase") == 0) && (argc == 2)) { cmd = CMD_ERASE; device = argv[1]; + } else if (((strcmp(argv[0], "resetbc") == 0) && (argc == 2)) && mtd_resetbc) { + cmd = CMD_RESETBC; + device = argv[1]; } else if (((strcmp(argv[0], "fixtrx") == 0) && (argc == 2)) && mtd_fixtrx) { cmd = CMD_FIXTRX; device = argv[1]; @@ -889,12 +966,16 @@ int main (int argc, char **argv) mtd_write_jffs2(device, imagefile, jffs2dir); break; case CMD_FIXTRX: - if (mtd_fixtrx) { - mtd_fixtrx(device, offset); - } + if (mtd_fixtrx) { + mtd_fixtrx(device, offset); + } + case CMD_RESETBC: + if (mtd_resetbc) { + mtd_resetbc(device); + } case CMD_FIXSEAMA: if (mtd_fixseama) - mtd_fixseama(device, 0); + mtd_fixseama(device, 0); break; }