Patches fstools to identify a jffs2 partition on nand by looking for the cleanmarker in the oob instead of at the start of an erase block.
Signed-off-by: Ben Mulvihill <ben.mulvih...@gmail.com> --- lib/mtd.c | 82 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 2 deletions(-) --- a/lib/mtd.c 2014-03-22 13:41:42.218663752 +0100 +++ b/lib/mtd.c 2014-03-23 15:49:00.549010963 +0100 @@ -158,12 +158,75 @@ mtd_write_buffer(int fd, void *buf, int return 0; } + +static __u8 +mtd_type(int fd) +{ + struct mtd_info_user mtdInfo; + + if (ioctl(fd, MEMGETINFO, &mtdInfo)) { + fprintf(stderr, "ioctl(%d, MEMGETINFO) failed: %s\n", fd, strerror(errno)); + return -1; + } + + return mtdInfo.type; +} + +static int +mtd_cleanmarker_nand(int fd) +{ + struct mtd_info_user mtdInfo; + + unsigned char oob[64]; + struct mtd_oob_buf oobBuf = {0, 16, oob}; + int i; + __u16 jffs2; + + if (ioctl(fd, MEMGETINFO, &mtdInfo)) { + fprintf(stderr, "ioctl(%d, MEMGETINFO) failed: %s\n", fd, strerror(errno)); + return -1; + } + + /* Read the real oob length */ + oobBuf.length = mtdInfo.oobsize; + if (oobBuf.length > sizeof (oob)) { + fprintf(stderr, "mtd_cleanmarker_nand(): oob too long"); + return -1; + } + + /* Read OOB data and exit on failure */ + oobBuf.start = 0; + if (ioctl(fd, MEMREADOOB, &oobBuf) != 0) { + fprintf(stderr, "ioctl(%d, MEMREADOOB) failed: %s\n", fd, strerror(errno)); + return -1; + } + + /* + The only way of finding out from userspace where the cleanmarker is + located within the oob seems to be to use an ioctl marked as obsolete. + So let's just search. + */ + + for (i = 0; i < oobBuf.length - 1; i++) + { + jffs2 = *(__u16 *)&oob[i]; + jffs2 = __be16_to_cpu(jffs2); + if (jffs2 == 0x1985) { + fprintf(stderr, "Cleanmarker found in oob at offset %d\n", i); + return 0; + } + } + return -1; +} + int mtd_identify(char *mtd) { int fd = mtd_load(mtd); __u32 deadc0de; __u16 jffs2; + __u8 type; + size_t sz; if (!fd) { @@ -172,30 +235,45 @@ mtd_identify(char *mtd) } sz = read(fd, &deadc0de, sizeof(deadc0de)); - close(fd); if (sz != sizeof(deadc0de)) { fprintf(stderr, "reading %s failed: %s\n", mtd, strerror(errno)); + close(fd); return -1; } - if (deadc0de == 0x4f575254) + if (deadc0de == 0x4f575254) { + close(fd); return FS_SNAPSHOT; + } deadc0de = __be32_to_cpu(deadc0de); jffs2 = __be16_to_cpu(deadc0de >> 16); if (jffs2 == 0x1985) { fprintf(stderr, "jffs2 is ready\n"); + close(fd); return FS_JFFS2; } if (deadc0de == 0xdeadc0de) { fprintf(stderr, "jffs2 is not ready - marker found\n"); + close(fd); return FS_DEADCODE; } + type = mtd_type (fd); + + if ((type == MTD_NANDFLASH) || (type == MTD_MLCNANDFLASH)) { + if (!mtd_cleanmarker_nand (fd)) { + fprintf(stderr, "jffs2 is ready\n"); + close(fd); + return FS_JFFS2; + } + } + fprintf(stderr, "No jffs2 marker was found\n"); + close(fd); return FS_NONE; } _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel