clean up mtd, fix up trx header when integrating jffs2 data on broadcom devices
authorFelix Fietkau <nbd@openwrt.org>
Tue, 23 Sep 2008 09:23:58 +0000 (09:23 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Tue, 23 Sep 2008 09:23:58 +0000 (09:23 +0000)
SVN-Revision: 12655

package/mtd/Makefile
package/mtd/src/Makefile
package/mtd/src/jffs2.c
package/mtd/src/mtd.c
package/mtd/src/mtd.h
package/mtd/src/trx.c [new file with mode: 0644]

index d8fa19c..b99e5ed 100644 (file)
@@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
 include $(INCLUDE_DIR)/kernel.mk
 
 PKG_NAME:=mtd
-PKG_RELEASE:=7
+PKG_RELEASE:=8
 
 PKG_BUILD_DIR := $(KERNEL_BUILD_DIR)/$(PKG_NAME)
 
@@ -32,10 +32,13 @@ define Build/Prepare
        $(CP) ./src/* $(PKG_BUILD_DIR)/
 endef
 
+target=$(firstword $(subst -, ,$(BOARD)))
+
 define Build/Compile
        $(MAKE) -C $(PKG_BUILD_DIR) \
                $(TARGET_CONFIGURE_OPTS) \
-               CFLAGS="$(TARGET_CFLAGS) -Dtarget_$(firstword $(subst -, ,$(BOARD)))=1"
+               TARGET=$(target) \
+               CFLAGS="$(TARGET_CFLAGS) -Dtarget_$(target)=1 -Wall"
 endef
 
 define Package/mtd/install
index 5ab7d7b..68a632d 100644 (file)
@@ -1,6 +1,10 @@
 CC = gcc
 CFLAGS += -Wall
 
-mtd: mtd.o jffs2.o crc32.o
+obj = mtd.o jffs2.o crc32.o
+obj.brcm = trx.o
+obj.brcm47xx = $(obj.brcm)
+
+mtd: $(obj) $(obj.$(TARGET))
 clean:
        rm -f *.o jffs2 
index d1c6fb6..5654f93 100644 (file)
@@ -140,7 +140,6 @@ static void add_file(const char *name, int parent)
        struct stat st;
        char wbuf[4096];
        const char *fname;
-       FILE *f;
 
        if (stat(name, &st)) {
                fprintf(stderr, "File %s does not exist\n", name);
@@ -210,7 +209,7 @@ static void add_file(const char *name, int parent)
        close(fd);
 }
 
-int mtd_replace_jffs2(int fd, int ofs, const char *filename)
+int mtd_replace_jffs2(const char *mtd, int fd, int ofs, const char *filename)
 {
        outfd = fd;
        mtdofs = ofs;
@@ -226,6 +225,11 @@ int mtd_replace_jffs2(int fd, int ofs, const char *filename)
        add_data(JFFS2_EOF, sizeof(JFFS2_EOF) - 1);
        pad(erasesize);
        free(buf);
+
+#ifdef target_brcm
+       trx_fixup(outfd, mtd);
+#endif
+       return 0;
 }
 
 void mtd_parse_jffs2data(const char *buf, const char *dir)
@@ -258,7 +262,6 @@ void mtd_parse_jffs2data(const char *buf, const char *dir)
 int mtd_write_jffs2(const char *mtd, const char *filename, const char *dir)
 {
        int err = -1, fdeof = 0;
-       off_t offset;
 
        outfd = mtd_check_open(mtd);
        if (!outfd)
@@ -326,6 +329,10 @@ int mtd_write_jffs2(const char *mtd, const char *filename, const char *dir)
 
        err = 0;
 
+#ifdef target_brcm
+       trx_fixup(outfd, mtd);
+#endif
+
 done:
        close(outfd);
        if (buf)
index 18a73a0..18c3e97 100644 (file)
 #include "mtd-api.h"
 #include "mtd.h"
 
-#ifdef target_brcm47xx
-#define target_brcm 1
-#endif
-
-#define TRX_MAGIC       0x30524448      /* "HDR0" */
 #define MAX_ARGS 8
-
-#define DEBUG
-
 #define JFFS2_DEFAULT_DIR      "" /* directory name without /, empty means root dir */
 
-#define SYSTYPE_UNKNOWN     0
-#define SYSTYPE_BROADCOM    1
-/* to be continued */
-
 struct trx_header {
        uint32_t magic;         /* "HDR0" */
        uint32_t len;           /* Length of file including header */
@@ -77,7 +65,7 @@ int quiet;
 int mtdsize = 0;
 int erasesize = 0;
 
-int mtd_open(const char *mtd)
+int mtd_open(const char *mtd, bool block)
 {
        FILE *fp;
        char dev[PATH_MAX];
@@ -88,9 +76,9 @@ int mtd_open(const char *mtd)
        if ((fp = fopen("/proc/mtd", "r"))) {
                while (fgets(dev, sizeof(dev), fp)) {
                        if (sscanf(dev, "mtd%d:", &i) && strstr(dev, mtd)) {
-                               snprintf(dev, sizeof(dev), "/dev/mtd/%d", i);
+                               snprintf(dev, sizeof(dev), "/dev/mtd%s/%d", (block ? "block" : ""), i);
                                if ((ret=open(dev, flags))<0) {
-                                       snprintf(dev, sizeof(dev), "/dev/mtd%d", i);
+                                       snprintf(dev, sizeof(dev), "/dev/mtd%s%d", (block ? "block" : ""), i);
                                        ret=open(dev, flags);
                                }
                                fclose(fp);
@@ -108,7 +96,7 @@ int mtd_check_open(const char *mtd)
        struct mtd_info_user mtdInfo;
        int fd;
 
-       fd = mtd_open(mtd);
+       fd = mtd_open(mtd, false);
        if(fd < 0) {
                fprintf(stderr, "Could not open mtd device: %s\n", mtd);
                return 0;
@@ -136,68 +124,22 @@ int mtd_erase_block(int fd, int offset)
                fprintf(stderr, "Erasing mtd failed.\n");
                exit(1);
        }
+       return 0;
 }
 
 int mtd_write_buffer(int fd, const char *buf, int offset, int length)
 {
        lseek(fd, offset, SEEK_SET);
        write(fd, buf, length);
+       return 0;
 }
 
 
-#ifdef target_brcm
-static int
-image_check_brcm(int imagefd, const char *mtd)
-{
-       struct trx_header *trx = (struct trx_header *) buf;
-       int fd;
-
-       if (strcmp(mtd, "linux") != 0)
-               return 1;
-       
-       buflen = read(imagefd, buf, 32);
-       if (buflen < 32) {
-               fprintf(stdout, "Could not get image header, file too small (%ld bytes)\n", buflen);
-               return 0;
-       }
-
-       if (trx->magic != TRX_MAGIC || trx->len < sizeof(struct trx_header)) {
-               if (quiet < 2) {
-                       fprintf(stderr, "Bad trx header\n");
-                       fprintf(stderr, "This is not the correct file format; refusing to flash.\n"
-                                       "Please specify the correct file or use -f to force.\n");
-               }
-               return 0;
-       }
-
-       /* check if image fits to mtd device */
-       fd = mtd_check_open(mtd);
-       if(fd < 0) {
-               fprintf(stderr, "Could not open mtd device: %s\n", mtd);
-               exit(1);
-       }
-
-       if(mtdsize < trx->len) {
-               fprintf(stderr, "Image too big for partition: %s\n", mtd);
-               close(fd);
-               return 0;
-       }       
-       
-       close(fd);
-       return 1;
-}
-#endif /* target_brcm */
-
 static int
 image_check(int imagefd, const char *mtd)
 {
-       int fd, systype;
-       size_t count;
-       char *c;
-       FILE *f;
-
 #ifdef target_brcm
-       return image_check_brcm(imagefd, mtd);
+       return trx_check(imagefd, mtd, buf, &buflen);
 #endif
 }
 
@@ -303,10 +245,8 @@ mtd_refresh(const char *mtd)
 static int
 mtd_write(int imagefd, const char *mtd)
 {
-       int fd, i, result;
+       int fd, result;
        size_t r, w, e;
-       struct erase_info_user mtdEraseInfo;
-       int ret = 0;
 
        fd = mtd_check_open(mtd);
        if(fd < 0) {
@@ -336,7 +276,7 @@ mtd_write(int imagefd, const char *mtd)
                                if (quiet < 2)
                                        fprintf(stderr, "\nAppending jffs2 data to from %s to %s...", jffs2file, mtd);
                                /* got an EOF marker - this is the place to add some jffs2 data */
-                               mtd_replace_jffs2(fd, e, jffs2file);
+                               mtd_replace_jffs2(mtd, fd, e, jffs2file);
                                goto done;
                        }
                        /* no EOF marker, make sure we figure out the last inode number
@@ -425,15 +365,15 @@ static void do_reboot(void)
 
 int main (int argc, char **argv)
 {
-       int ch, i, boot, unlock, imagefd, force, unlocked;
-       char *erase[MAX_ARGS], *device;
+       int ch, i, boot, imagefd = 0, force, unlocked;
+       char *erase[MAX_ARGS], *device = NULL;
        enum {
                CMD_ERASE,
                CMD_WRITE,
                CMD_UNLOCK,
                CMD_REFRESH,
                CMD_JFFS2WRITE
-       } cmd;
+       } cmd = -1;
        
        erase[0] = NULL;
        boot = 0;
index 42b6610..a018031 100644 (file)
@@ -1,18 +1,28 @@
 #ifndef __mtd_h
 #define __mtd_h
 
+#include <stdbool.h>
+
+#ifdef target_brcm47xx
+#define target_brcm 1
+#endif
+
 #define JFFS2_EOF "\xde\xad\xc0\xde"
 
 extern int quiet;
 extern int mtdsize;
 extern int erasesize;
 
-extern int mtd_open(const char *mtd);
+extern int mtd_open(const char *mtd, bool block);
 extern int mtd_check_open(const char *mtd);
 extern int mtd_erase_block(int fd, int offset);
 extern int mtd_write_buffer(int fd, const char *buf, int offset, int length);
 extern int mtd_write_jffs2(const char *mtd, const char *filename, const char *dir);
-extern int mtd_replace_jffs2(int fd, int ofs, const char *filename);
+extern int mtd_replace_jffs2(const char *mtd, int fd, int ofs, const char *filename);
 extern void mtd_parse_jffs2data(const char *buf, const char *dir);
 
+/* target specific */
+extern int trx_fixup(int fd, const char *name);
+extern int trx_check(int imagefd, const char *mtd, char *buf, int *len);
+
 #endif /* __mtd_h */
diff --git a/package/mtd/src/trx.c b/package/mtd/src/trx.c
new file mode 100644 (file)
index 0000000..5457a36
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * trx.c
+ *
+ * Copyright (C) 2005 Mike Baker 
+ * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <string.h>
+
+#include <sys/ioctl.h>
+#include "mtd-api.h"
+#include "mtd.h"
+
+#define TRX_MAGIC       0x30524448      /* "HDR0" */
+struct trx_header {
+       unsigned magic;         /* "HDR0" */
+       unsigned len;           /* Length of file including header */
+       unsigned crc32;         /* 32-bit CRC from flag_version to end of file */
+       unsigned flag_version;  /* 0:15 flags, 16:31 version */
+       unsigned offsets[3];    /* Offsets of partitions from start of header */
+};
+
+static unsigned long *crc32 = NULL;
+
+static void init_crc32()
+{
+       unsigned long crc;
+       unsigned long poly = 0xEDB88320L;
+       int n, bit;
+
+       if (crc32)
+               return;
+
+       crc32 = (unsigned long *) malloc(256 * sizeof(unsigned long));
+       if (!crc32) {
+               perror("malloc");
+               exit(1);
+       }
+
+       for (n = 0; n < 256; n++) {
+               crc = (unsigned long) n;
+               for (bit = 0; bit < 8; bit++)
+                       crc = (crc & 1) ? (poly ^ (crc >> 1)) : (crc >> 1);
+               crc32[n] = crc;
+       }
+}
+
+static unsigned int crc32buf(char *buf, size_t len)
+{
+       unsigned int crc = 0xFFFFFFFF;
+       for (; len; len--, buf++)
+               crc = crc32[(crc ^ *buf) & 0xff] ^ (crc >> 8);
+       return crc;
+}
+
+int
+trx_fixup(int fd, const char *name)
+{
+       struct mtd_info_user mtdInfo;
+       unsigned long len;
+       struct trx_header *trx;
+       void *ptr, *scan;
+       int bfd;
+
+       if (ioctl(fd, MEMGETINFO, &mtdInfo) < 0) {
+               fprintf(stderr, "Failed to get mtd info\n");
+               goto err;
+       }
+
+       len = mtdInfo.size;
+       if (mtdInfo.size <= 0) {
+               fprintf(stderr, "Invalid MTD device size\n");
+               goto err;
+       }
+
+       bfd = mtd_open(name, true);
+       ptr = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, bfd, 0);
+       if (!ptr || (ptr == (void *) -1)) {
+               perror("mmap");
+               goto err1;
+       }
+
+       trx = ptr;
+       if (trx->magic != TRX_MAGIC) {
+               fprintf(stderr, "TRX header not found\n");
+               goto err;
+       }
+
+       init_crc32();
+       scan = ptr + offsetof(struct trx_header, flag_version);
+       trx->crc32 = crc32buf(scan, trx->len - (scan - ptr));
+       msync(ptr, sizeof(struct trx_header), MS_SYNC|MS_INVALIDATE);
+       munmap(ptr, len);
+       close(bfd);
+       return 0;
+
+err1:
+       close(bfd);
+err:
+       fprintf(stderr, "Error fixing up TRX header\n");
+       return -1;
+}
+
+int
+trx_check(int imagefd, const char *mtd, char *buf, int *len)
+{
+       const struct trx_header *trx = (const struct trx_header *) buf;
+       int fd;
+
+       if (strcmp(mtd, "linux") != 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;
+       }
+
+       if (trx->magic != TRX_MAGIC || trx->len < sizeof(struct trx_header)) {
+               if (quiet < 2) {
+                       fprintf(stderr, "Bad trx header\n");
+                       fprintf(stderr, "This is not the correct file format; refusing to flash.\n"
+                                       "Please specify the correct file or use -f to force.\n");
+               }
+               return 0;
+       }
+
+       /* check if image fits to mtd device */
+       fd = mtd_check_open(mtd);
+       if(fd < 0) {
+               fprintf(stderr, "Could not open mtd device: %s\n", mtd);
+               exit(1);
+       }
+
+       if(mtdsize < trx->len) {
+               fprintf(stderr, "Image too big for partition: %s\n", mtd);
+               close(fd);
+               return 0;
+       }
+
+       close(fd);
+       return 1;
+}
+