Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Index: package/mtd/src/fis.c
- ===================================================================
- --- package/mtd/src/fis.c (revision 20862)
- +++ package/mtd/src/fis.c (working copy)
- @@ -42,51 +42,29 @@
- struct fis_image_crc crc;
- } __attribute__((packed));
- -static int fis_fd = -1;
- +static struct mtd_device *fisdev = NULL;
- static struct fis_image_desc *fis_desc;
- -static int fis_erasesize = 0;
- static void
- fis_close(void)
- {
- - if (fis_desc)
- - munmap(fis_desc, fis_erasesize);
- -
- - if (fis_fd >= 0)
- - close(fis_fd);
- -
- - fis_fd = -1;
- + mtd_close(fisdev);
- + fisdev = NULL;
- fis_desc = NULL;
- }
- static struct fis_image_desc *
- fis_open(void)
- {
- - struct fis_image_desc *desc;
- -
- - if (fis_fd >= 0)
- + if (fisdev)
- fis_close();
- - fis_fd = mtd_check_open("FIS directory");
- - if (fis_fd < 0)
- - goto error;
- + fisdev = mtd_open("FIS directory", true);
- + if (!fisdev)
- + return NULL;
- - close(fis_fd);
- - fis_fd = mtd_open("FIS directory", true);
- - if (fis_fd < 0)
- - goto error;
- -
- - fis_erasesize = erasesize;
- - desc = mmap(NULL, erasesize, PROT_READ|PROT_WRITE, MAP_SHARED, fis_fd, 0);
- - if (desc == MAP_FAILED)
- - goto error;
- -
- - fis_desc = desc;
- - return desc;
- -
- -error:
- - fis_close();
- - return NULL;
- + fis_desc = fisdev->mmap;;
- + return fis_desc;
- }
- int
- @@ -110,7 +88,7 @@
- }
- end = desc;
- - end = (char *) end + fis_erasesize;
- + end = (char *) end + fisdev->info.erasesize;
- while ((void *) desc < end) {
- if (!desc->hdr.name[0] || (desc->hdr.name[0] == 0xff))
- break;
- @@ -157,7 +135,7 @@
- fprintf(stderr, "Updating FIS table... \n");
- start = (char *) desc;
- - end = (char *) desc + fis_erasesize;
- + end = (char *) desc + fisdev->info.erasesize;
- while ((char *) desc < end) {
- if (!desc->hdr.name[0] || (desc->hdr.name[0] == 0xff))
- break;
- @@ -245,7 +223,7 @@
- size -= desc->hdr.size;
- }
- - msync(fis_desc, fis_erasesize, MS_SYNC|MS_INVALIDATE);
- + msync(fis_desc, fisdev->info.erasesize, MS_SYNC|MS_INVALIDATE);
- fis_close();
- return 0;
- Index: package/mtd/src/mtd.c
- ===================================================================
- --- package/mtd/src/mtd.c (revision 20862)
- +++ package/mtd/src/mtd.c (working copy)
- @@ -1,8 +1,9 @@
- /*
- * mtd - simple memory technology device manipulation tool
- *
- - * Copyright (C) 2005 Waldemar Brodkorb <wbx@dass-it.de>,
- + * Copyright (C) 2005 Waldemar Brodkorb <wbx@dass-it.de>
- * Copyright (C) 2005-2009 Felix Fietkau <nbd@openwrt.org>
- + * Copyright (C) 2010 Bernhard Loos <bernhardloos@googlemail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License v2
- @@ -21,7 +22,6 @@
- * The code is based on the linux-mtd examples.
- */
- -#include <limits.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- @@ -31,350 +31,68 @@
- #include <sys/syscall.h>
- #include <fcntl.h>
- #include <errno.h>
- -#include <error.h>
- -#include <time.h>
- #include <string.h>
- -#include <sys/ioctl.h>
- -#include <sys/types.h>
- -#include <sys/param.h>
- -#include <sys/mount.h>
- -#include <sys/stat.h>
- #include <sys/reboot.h>
- #include <linux/reboot.h>
- -#include "mtd-api.h"
- #include "fis.h"
- #include "mtd.h"
- -#include "crc32.h"
- #define MAX_ARGS 8
- #define JFFS2_DEFAULT_DIR "" /* directory name without /, empty means root dir */
- -#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
- -#define STORE32_LE(X) (X)
- -#else
- -#error unkown endianness!
- -#endif
- -
- -ssize_t pread(int fd, void *buf, size_t count, off_t offset);
- -ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);
- -
- -#define TRX_MAGIC 0x30524448 /* "HDR0" */
- -struct trx_header {
- - uint32_t magic; /* "HDR0" */
- - uint32_t len; /* Length of file including header */
- - uint32_t crc32; /* 32-bit CRC from flag_version to end of file */
- - uint32_t flag_version; /* 0:15 flags, 16:31 version */
- - uint32_t offsets[3]; /* Offsets of partitions from start of header */
- -};
- -
- static char *buf = NULL;
- static char *imagefile = NULL;
- static char *jffs2file = NULL, *jffs2dir = JFFS2_DEFAULT_DIR;
- static int buflen = 0;
- int quiet;
- -int mtdsize = 0;
- -int erasesize = 0;
- -int mtd_open(const char *mtd, bool block)
- -{
- - FILE *fp;
- - char dev[PATH_MAX];
- - int i;
- - int ret;
- - int flags = O_RDWR | O_SYNC;
- +struct platform_imageops imageops __attribute__((weak)) = {
- + .firmware_partition = "firmware"
- +};
- - 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%s/%d", (block ? "block" : ""), i);
- - if ((ret=open(dev, flags))<0) {
- - snprintf(dev, sizeof(dev), "/dev/mtd%s%d", (block ? "block" : ""), i);
- - ret=open(dev, flags);
- - }
- - fclose(fp);
- - return ret;
- - }
- - }
- - fclose(fp);
- - }
- -
- - return open(mtd, flags);
- -}
- -
- -int mtd_check_open(const char *mtd)
- -{
- - struct mtd_info_user mtdInfo;
- - int fd;
- -
- - fd = mtd_open(mtd, false);
- - if(fd < 0) {
- - fprintf(stderr, "Could not open mtd device: %s\n", mtd);
- - return -1;
- - }
- -
- - if(ioctl(fd, MEMGETINFO, &mtdInfo)) {
- - fprintf(stderr, "Could not get MTD device info from %s\n", mtd);
- - close(fd);
- - return -1;
- - }
- - mtdsize = mtdInfo.size;
- - erasesize = mtdInfo.erasesize;
- -
- - return fd;
- -}
- -
- -int mtd_erase_block(int fd, int offset)
- -{
- - struct erase_info_user mtdEraseInfo;
- -
- - mtdEraseInfo.start = offset;
- - mtdEraseInfo.length = erasesize;
- - ioctl(fd, MEMUNLOCK, &mtdEraseInfo);
- - if (ioctl (fd, MEMERASE, &mtdEraseInfo) < 0)
- - return -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;
- -}
- -
- -
- static int
- -image_check(int imagefd, const char *mtd)
- +cmd_erase(struct mtd_device **mtddevs)
- {
- - int ret = 1;
- -#ifdef target_brcm
- - ret = trx_check(imagefd, mtd, buf, &buflen);
- -#endif
- - return ret;
- -}
- -
- -static int mtd_check(const char *mtd)
- -{
- - char *next = NULL;
- - char *str = NULL;
- - int fd;
- -
- - if (strchr(mtd, ':')) {
- - str = strdup(mtd);
- - mtd = str;
- - }
- -
- - do {
- - next = strchr(mtd, ':');
- - if (next) {
- - *next = 0;
- - next++;
- - }
- -
- - fd = mtd_check_open(mtd);
- - if (fd < 0)
- - return 0;
- -
- - if (!buf)
- - buf = malloc(erasesize);
- -
- - close(fd);
- - mtd = next;
- - } while (next);
- -
- - if (str)
- - free(str);
- -
- - return 1;
- -}
- -
- -static int
- -mtd_unlock(const char *mtd)
- -{
- - struct erase_info_user mtdLockInfo;
- - char *next = NULL;
- - char *str = NULL;
- - int fd;
- -
- - if (strchr(mtd, ':')) {
- - str = strdup(mtd);
- - mtd = str;
- - }
- -
- - do {
- - next = strchr(mtd, ':');
- - if (next) {
- - *next = 0;
- - next++;
- - }
- -
- - fd = mtd_check_open(mtd);
- - if(fd < 0) {
- - fprintf(stderr, "Could not open mtd device: %s\n", mtd);
- - exit(1);
- - }
- -
- + int i = 0;
- + int ret;
- +
- + while (mtddevs[i]) {
- if (quiet < 2)
- - fprintf(stderr, "Unlocking %s ...\n", mtd);
- -
- - mtdLockInfo.start = 0;
- - mtdLockInfo.length = mtdsize;
- - ioctl(fd, MEMUNLOCK, &mtdLockInfo);
- - close(fd);
- - mtd = next;
- - } while (next);
- -
- - if (str)
- - free(str);
- -
- - return 0;
- -}
- -
- -static int
- -mtd_erase(const char *mtd)
- -{
- - int fd;
- - struct erase_info_user mtdEraseInfo;
- -
- - if (quiet < 2)
- - fprintf(stderr, "Erasing %s ...\n", mtd);
- -
- - fd = mtd_check_open(mtd);
- - if(fd < 0) {
- - fprintf(stderr, "Could not open mtd device: %s\n", mtd);
- - exit(1);
- + fprintf(stderr, "Erasing %s ...\n", mtddevs[i]->name);
- +
- + ret = mtd_erase(mtddevs[i++]);
- + if (ret < 0)
- + return ret;
- }
- -
- - mtdEraseInfo.length = erasesize;
- -
- - for (mtdEraseInfo.start = 0;
- - mtdEraseInfo.start < mtdsize;
- - mtdEraseInfo.start += erasesize) {
- -
- - ioctl(fd, MEMUNLOCK, &mtdEraseInfo);
- - if(ioctl(fd, MEMERASE, &mtdEraseInfo))
- - fprintf(stderr, "Failed to erase block on %s at 0x%x\n", mtd, mtdEraseInfo.start);
- - }
- -
- - close(fd);
- +
- return 0;
- -
- }
- static int
- -mtd_fixtrx(const char *mtd, size_t offset)
- +cmd_refresh(struct mtd_device **mtddevs)
- {
- - int fd;
- - struct trx_header *trx;
- - char *buf;
- - ssize_t res;
- - size_t block_offset;
- -
- - if (quiet < 2)
- - fprintf(stderr, "Trying to fix trx header in %s at 0x%x...\n", mtd, offset);
- -
- - block_offset = offset & ~(erasesize - 1);
- - offset -= block_offset;
- -
- - fd = mtd_check_open(mtd);
- - if(fd < 0) {
- - fprintf(stderr, "Could not open mtd device: %s\n", mtd);
- - exit(1);
- - }
- -
- - if (block_offset + erasesize > mtdsize) {
- - fprintf(stderr, "Offset too large, device size 0x%x\n", mtdsize);
- - exit(1);
- - }
- -
- - buf = malloc(erasesize);
- - if (!buf) {
- - perror("malloc");
- - exit(1);
- - }
- -
- - res = pread(fd, buf, erasesize, block_offset);
- - if (res != erasesize) {
- - perror("pread");
- - exit(1);
- - }
- -
- - trx = (struct trx_header *) (buf + offset);
- - if (trx->magic != STORE32_LE(0x30524448)) {
- - fprintf(stderr, "No trx magic found\n");
- - exit(1);
- - }
- -
- - if (trx->len == STORE32_LE(erasesize - offset)) {
- + int i = 0;
- + int ret;
- +
- + while (mtddevs[i]) {
- if (quiet < 2)
- - fprintf(stderr, "Header already fixed, exiting\n");
- - close(fd);
- - return 0;
- + fprintf(stderr, "Refreshing mtd partition %s ... \n", mtddevs[i]->name);
- +
- + ret = ioctl(mtddevs[i++]->fd, MTDREFRESH, NULL);
- + if (ret < 0)
- + return ret;
- }
- -
- - trx->len = STORE32_LE(erasesize - offset);
- -
- - trx->crc32 = STORE32_LE(crc32buf((char*) &trx->flag_version, erasesize - offset - 3*4));
- - if (mtd_erase_block(fd, block_offset)) {
- - fprintf(stderr, "Can't erease block at 0x%x (%s)\n", block_offset, strerror(errno));
- - exit(1);
- - }
- -
- - if (quiet < 2)
- - fprintf(stderr, "New crc32: 0x%x, rewriting block\n", trx->crc32);
- -
- - if (pwrite(fd, buf, erasesize, block_offset) != erasesize) {
- - fprintf(stderr, "Error writing block (%s)\n", strerror(errno));
- - exit(1);
- - }
- -
- - if (quiet < 2)
- - fprintf(stderr, "Done.\n");
- -
- - close (fd);
- - sync();
- +
- return 0;
- -
- }
- static int
- -mtd_refresh(const char *mtd)
- +cmd_write(int imagefd, struct mtd_device **mtddevs, char *fis_layout)
- {
- - int fd;
- -
- - if (quiet < 2)
- - fprintf(stderr, "Refreshing mtd partition %s ... ", mtd);
- -
- - fd = mtd_check_open(mtd);
- - if(fd < 0) {
- - fprintf(stderr, "Could not open mtd device: %s\n", mtd);
- - exit(1);
- - }
- -
- - if (ioctl(fd, MTDREFRESH, NULL)) {
- - fprintf(stderr, "Failed to refresh the MTD device\n");
- - close(fd);
- - exit(1);
- - }
- - close(fd);
- -
- - if (quiet < 2)
- - fprintf(stderr, "\n");
- -
- - return 0;
- -}
- -
- -static int
- -mtd_write(int imagefd, const char *mtd, char *fis_layout)
- -{
- - char *next = NULL;
- - char *str = NULL;
- - int fd, result;
- + int result;
- ssize_t r, w, e;
- uint32_t offset = 0;
- + int i;
- #ifdef FIS_SUPPORT
- static struct fis_part new_parts[MAX_ARGS];
- @@ -382,24 +100,19 @@
- int n_new = 0, n_old = 0;
- if (fis_layout) {
- - const char *tmp = mtd;
- + const char *tmp;
- char *word, *brkt;
- int ret;
- memset(&old_parts, 0, sizeof(old_parts));
- memset(&new_parts, 0, sizeof(new_parts));
- - do {
- - next = strchr(tmp, ':');
- - if (!next)
- - next = (char *) tmp + strlen(tmp);
- + i = 0;
- + while (mtddevs[i]) {
- + memcpy(old_parts[n_old++].name, mtddevs[i]->name, strlen(mtddevs[i]->name));
- + i++;
- + }
- - memcpy(old_parts[n_old].name, tmp, next - tmp);
- -
- - n_old++;
- - tmp = next + 1;
- - } while(*next);
- -
- for (word = strtok_r(fis_layout, ",", &brkt);
- word;
- word = strtok_r(NULL, ",", &brkt)) {
- @@ -431,28 +144,11 @@
- }
- #endif
- - if (strchr(mtd, ':')) {
- - str = strdup(mtd);
- - mtd = str;
- - }
- -
- r = 0;
- -
- + i = 0;
- resume:
- - next = strchr(mtd, ':');
- - if (next) {
- - *next = 0;
- - next++;
- - }
- -
- - fd = mtd_check_open(mtd);
- - if(fd < 0) {
- - fprintf(stderr, "Could not open mtd device: %s\n", mtd);
- - exit(1);
- - }
- -
- if (quiet < 2)
- - fprintf(stderr, "Writing from %s to %s ... ", imagefile, mtd);
- + fprintf(stderr, "Writing from %s to %s ... ", imagefile, mtddevs[i]->name);
- w = e = 0;
- if (!quiet)
- @@ -460,8 +156,8 @@
- for (;;) {
- /* buffer may contain data already (from trx check or last mtd partition write attempt) */
- - while (buflen < erasesize) {
- - r = read(imagefd, buf + buflen, erasesize - buflen);
- + while (buflen < mtddevs[i]->info.erasesize) {
- + r = read(imagefd, buf + buflen, mtddevs[i]->info.erasesize - buflen);
- if (r < 0) {
- if ((errno == EINTR) || (errno == EAGAIN))
- continue;
- @@ -485,9 +181,9 @@
- if (!quiet)
- fprintf(stderr, "\b\b\b ");
- if (quiet < 2)
- - fprintf(stderr, "\nAppending jffs2 data from %s to %s...", jffs2file, mtd);
- + fprintf(stderr, "\nAppending jffs2 data from %s to %s...", jffs2file, mtddevs[i]->name);
- /* got an EOF marker - this is the place to add some jffs2 data */
- - mtd_replace_jffs2(mtd, fd, e, jffs2file);
- + mtd_replace_jffs2(mtddevs[i], e, jffs2file);
- goto done;
- }
- /* no EOF marker, make sure we figure out the last inode number
- @@ -501,16 +197,15 @@
- fprintf(stderr, "\b\b\b[e]");
- - if (mtd_erase_block(fd, e) < 0) {
- - if (next) {
- + if (mtd_erase_block(mtddevs[i], e) < 0) {
- + if (mtddevs[i + 1]) {
- if (w < e) {
- - write(fd, buf + offset, e - w);
- + write(mtddevs[i]->fd, buf + offset, e - w);
- offset = e - w;
- }
- w = 0;
- e = 0;
- - close(fd);
- - mtd = next;
- + i++;
- fprintf(stderr, "\b\b\b \n");
- goto resume;
- } else {
- @@ -520,13 +215,13 @@
- }
- /* erase the chunk */
- - e += erasesize;
- + e += mtddevs[i]->info.erasesize;
- }
- if (!quiet)
- fprintf(stderr, "\b\b\b[w]");
- - if ((result = write(fd, buf + offset, buflen)) < buflen) {
- + if ((result = write(mtddevs[i]->fd, buf + offset, buflen)) < buflen) {
- if (result < 0) {
- fprintf(stderr, "Error writing image.\n");
- exit(1);
- @@ -555,7 +250,6 @@
- }
- #endif
- - close(fd);
- return 0;
- }
- @@ -569,7 +263,7 @@
- " erase erase all data on device\n"
- " write <imagefile>|- write <imagefile> (use - for stdin) to device\n"
- " jffs2write <file> append <file> to the jffs2 partition on the device\n"
- - " fixtrx fix the checksum in a trx header on first boot\n"
- + " fixcrc fix the checksum in the image header on first boot (device is not needed)\n"
- "Following options are available:\n"
- " -q quiet mode (once: no [w] on writing,\n"
- " twice: no status messages)\n"
- @@ -578,7 +272,6 @@
- " -e <device> erase <device> before executing the command\n"
- " -d <name> directory for jffs2write, defaults to \"tmp\"\n"
- " -j <name> integrate <file> into jffs2 data when writing an image\n"
- - " -o offset offset of the trx header in the partition (for fixtrx)\n"
- #ifdef FIS_SUPPORT
- " -F <part>[:<size>[:<entrypoint>]][,<part>...]\n"
- " alter the fis partition table to create new partitions replacing\n"
- @@ -606,19 +299,19 @@
- int main (int argc, char **argv)
- {
- - int ch, i, boot, imagefd = 0, force, unlocked;
- + int ch, i, boot, imagefd = 0, force;
- char *erase[MAX_ARGS], *device = NULL;
- char *fis_layout = NULL;
- - size_t offset = 0;
- + struct mtd_device **mtddevs;
- enum {
- CMD_ERASE,
- CMD_WRITE,
- CMD_UNLOCK,
- CMD_REFRESH,
- CMD_JFFS2WRITE,
- - CMD_FIXTRX,
- + CMD_FIXCRC,
- } cmd = -1;
- -
- +
- erase[0] = NULL;
- boot = 0;
- force = 0;
- @@ -629,7 +322,7 @@
- #ifdef FIS_SUPPORT
- "F:"
- #endif
- - "frqe:d:j:o:")) != -1)
- + "frqe:d:j:")) != -1)
- switch (ch) {
- case 'f':
- force = 1;
- @@ -654,14 +347,6 @@
- case 'd':
- jffs2dir = optarg;
- break;
- - case 'o':
- - errno = 0;
- - offset = strtoul(optarg, 0, 0);
- - if (errno) {
- - fprintf(stderr, "-o: illegal numeric string\n");
- - usage();
- - }
- - break;
- #ifdef FIS_SUPPORT
- case 'F':
- fis_layout = optarg;
- @@ -674,7 +359,7 @@
- argc -= optind;
- argv += optind;
- - if (argc < 2)
- + if (argc < 1)
- usage();
- if ((strcmp(argv[0], "unlock") == 0) && (argc == 2)) {
- @@ -686,9 +371,28 @@
- } else if ((strcmp(argv[0], "erase") == 0) && (argc == 2)) {
- cmd = CMD_ERASE;
- device = argv[1];
- - } else if ((strcmp(argv[0], "fixtrx") == 0) && (argc == 2)) {
- - cmd = CMD_FIXTRX;
- - device = argv[1];
- + } else if ((strcmp(argv[0], "fixcrc") == 0) && (argc == 1)) {
- + struct mtd_device *mtd = 0;
- + int res;
- +
- + cmd = CMD_FIXCRC;
- +
- + if (imageops.checkimage) {
- + mtd = mtd_open(imageops.firmware_partition, true);
- + if (!mtd)
- + exit(1);
- + if (quiet < 2)
- + fprintf(stderr, "Checking image and fixing crc ...\n");
- + res = imageops.checkimage((char *) mtd->mmap, mtd->info.erasesize, mtd->info.size);
- + if (res < 0) {
- + fprintf(stderr, "Image check failed.\n");
- + exit(1);
- + } else if (res > 0 && quiet < 2)
- + fprintf(stderr, "CRC already fixed\n");
- + }
- +
- + mtd_close(mtd);
- + return 0; /* leave early, there is nothing else to do for us */
- } else if ((strcmp(argv[0], "write") == 0) && (argc == 3)) {
- cmd = CMD_WRITE;
- device = argv[2];
- @@ -703,68 +407,102 @@
- exit(1);
- }
- }
- -
- - if (!mtd_check(device)) {
- - fprintf(stderr, "Can't open device for writing!\n");
- - exit(1);
- - }
- - /* check trx file before erasing or writing anything */
- - if (!image_check(imagefd, device) && !force) {
- - fprintf(stderr, "Image check failed.\n");
- - exit(1);
- - }
- } else if ((strcmp(argv[0], "jffs2write") == 0) && (argc == 3)) {
- cmd = CMD_JFFS2WRITE;
- device = argv[2];
- imagefile = argv[1];
- - if (!mtd_check(device)) {
- - fprintf(stderr, "Can't open device for writing!\n");
- - exit(1);
- - }
- } else {
- usage();
- }
- sync();
- + mtddevs = mtd_open_multiple(device);
- + if (!mtddevs)
- + exit(1);
- +
- + buf = malloc(mtddevs[0]->info.erasesize);
- + if (!buf) {
- + perror("malloc");
- + exit(1);
- + }
- +
- + if (strcmp(device, imageops.firmware_partition) == 0 && imageops.checkimage && !force && cmd == CMD_WRITE) {
- + int res;
- + size_t mtd_length = 0;
- + int i = 0;
- +
- + while (mtddevs[i])
- + mtd_length += mtddevs[i++]->info.size;
- +
- + buflen = read(imagefd, buf, mtddevs[0]->info.erasesize);
- + if (buflen < mtddevs[0]->info.erasesize) {
- + fprintf(stdout, "Could not get image header, file too small (%d bytes)\n", buflen);
- + exit(1);
- + }
- +
- + if (quiet < 2)
- + fprintf(stderr, "Checking image and fixing crc ...\n");
- + res = imageops.checkimage(buf, buflen, mtd_length);
- + if (res < 0) {
- + fprintf(stderr, "Image check failed.\n");
- + exit(1);
- + } else if (res > 0 && quiet < 2)
- + fprintf(stderr, "CRC already fixed\n");
- + }
- +
- i = 0;
- - unlocked = 0;
- while (erase[i] != NULL) {
- - mtd_unlock(erase[i]);
- - mtd_erase(erase[i]);
- - if (strcmp(erase[i], device) == 0)
- - unlocked = 1;
- + struct mtd_device *erasedev;
- + int j = 0;
- +
- + while (mtddevs[j]) {
- + if (strcmp(erase[i], mtddevs[j]->name) == 0)
- + erasedev = mtddevs[j];
- + j++;
- + }
- + if (!mtddevs[j])
- + erasedev = mtd_open(erase[i], false);
- + if (!erasedev)
- + exit(1);
- + mtd_unlock(erasedev);
- + mtd_erase(erasedev);
- + if (!mtddevs[j])
- + mtd_close(erasedev);
- +
- i++;
- }
- -
- +
- + i = 0;
- + while (mtddevs[i]) {
- + if (quiet < 2)
- + fprintf(stderr, "Unlocking %s ...\n", mtddevs[i]->name);
- + mtd_unlock(mtddevs[i++]);
- + }
- +
- switch (cmd) {
- case CMD_UNLOCK:
- - if (!unlocked)
- - mtd_unlock(device);
- + /* nothing to do */
- break;
- case CMD_ERASE:
- - if (!unlocked)
- - mtd_unlock(device);
- - mtd_erase(device);
- + cmd_erase(mtddevs);
- break;
- case CMD_WRITE:
- - if (!unlocked)
- - mtd_unlock(device);
- - mtd_write(imagefd, device, fis_layout);
- + cmd_write(imagefd, mtddevs, fis_layout);
- break;
- case CMD_JFFS2WRITE:
- - if (!unlocked)
- - mtd_unlock(device);
- - mtd_write_jffs2(device, imagefile, jffs2dir);
- + cmd_write_jffs2(mtddevs, imagefile, jffs2dir);
- break;
- case CMD_REFRESH:
- - mtd_refresh(device);
- + cmd_refresh(mtddevs);
- break;
- - case CMD_FIXTRX:
- - mtd_fixtrx(device, offset);
- + case CMD_FIXCRC:
- + /* nothing to do */
- break;
- }
- +
- + mtd_close_multiple(mtddevs);
- sync();
- Index: package/mtd/src/mtd.h
- ===================================================================
- --- package/mtd/src/mtd.h (revision 20862)
- +++ package/mtd/src/mtd.h (working copy)
- @@ -3,6 +3,8 @@
- #include <stdbool.h>
- +#include "mtd-api.h"
- +
- #ifdef target_brcm47xx
- #define target_brcm 1
- #endif
- @@ -10,19 +12,30 @@
- #define JFFS2_EOF "\xde\xad\xc0\xde"
- extern int quiet;
- -extern int mtdsize;
- -extern int erasesize;
- -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(const char *mtd, int fd, int ofs, const char *filename);
- +struct mtd_device {
- + const char *name;
- + int fd;
- + struct mtd_info_user info;
- + int unlocked : 1;
- + void *mmap; /* only first eraseblock */
- +};
- +
- +extern struct mtd_device *mtd_open(const char *mtd, bool block);
- +extern struct mtd_device **mtd_open_multiple(const char *mtds);
- +extern void mtd_close_multiple(struct mtd_device **mtds);
- +extern void mtd_close(struct mtd_device *mtd);
- +extern int mtd_erase_block(struct mtd_device *mtd, size_t offset);
- +extern int mtd_erase(struct mtd_device *mtd);
- +extern int mtd_unlock(struct mtd_device *mtd);
- +
- +extern int cmd_write_jffs2(struct mtd_device **mtds, const char *filename, const char *dir);
- +extern int mtd_replace_jffs2(struct mtd_device *mtd, 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);
- +struct platform_imageops {
- + int (*checkimage)(char *imagedata, size_t datalength, size_t mtdlength);
- + const char *firmware_partition;
- +};
- #endif /* __mtd_h */
- Index: package/mtd/src/jffs2.c
- ===================================================================
- --- package/mtd/src/jffs2.c (revision 20862)
- +++ package/mtd/src/jffs2.c (working copy)
- @@ -42,7 +42,8 @@
- static int last_version = 0;
- static char *buf = NULL;
- static int ofs = 0;
- -static int outfd = -1;
- +static struct mtd_device *mtddev = NULL;
- +static int erasesize = 0;
- static int mtdofs = 0;
- static int target_ino = 0;
- @@ -59,8 +60,8 @@
- }
- ofs = ofs % erasesize;
- if (ofs == 0) {
- - mtd_erase_block(outfd, mtdofs);
- - write(outfd, buf, erasesize);
- + mtd_erase_block(mtddev, mtdofs);
- + write(mtddev->fd, buf, erasesize);
- mtdofs += erasesize;
- }
- }
- @@ -227,9 +228,10 @@
- close(fd);
- }
- -int mtd_replace_jffs2(const char *mtd, int fd, int ofs, const char *filename)
- +int mtd_replace_jffs2(struct mtd_device *mtd, int ofs, const char *filename)
- {
- - outfd = fd;
- + mtddev = mtd;
- + erasesize = mtd->info.erasesize;
- mtdofs = ofs;
- buf = malloc(erasesize);
- @@ -244,9 +246,6 @@
- pad(erasesize);
- free(buf);
- -#ifdef target_brcm
- - trx_fixup(outfd, mtd);
- -#endif
- return 0;
- }
- @@ -277,16 +276,15 @@
- }
- }
- -int mtd_write_jffs2(const char *mtd, const char *filename, const char *dir)
- +int cmd_write_jffs2(struct mtd_device **mtd, const char *filename, const char *dir)
- {
- int err = -1, fdeof = 0;
- - outfd = mtd_check_open(mtd);
- - if (outfd < 0)
- - return -1;
- + mtddev = mtd[0];
- + erasesize = mtddev->info.erasesize;
- if (quiet < 2)
- - fprintf(stderr, "Appending %s to jffs2 partition %s\n", filename, mtd);
- + fprintf(stderr, "Appending %s to jffs2 partition %s\n", filename, mtddev->name);
- buf = malloc(erasesize);
- if (!buf) {
- @@ -302,7 +300,7 @@
- for(;;) {
- struct jffs2_unknown_node *node = (struct jffs2_unknown_node *) buf;
- - if (read(outfd, buf, erasesize) != erasesize) {
- + if (read(mtddev->fd, buf, erasesize) != erasesize) {
- fdeof = 1;
- break;
- }
- @@ -328,7 +326,7 @@
- /* jump back one eraseblock */
- mtdofs -= erasesize;
- - lseek(outfd, mtdofs, SEEK_SET);
- + lseek(mtddev->fd, mtdofs, SEEK_SET);
- ofs = 0;
- @@ -347,12 +345,7 @@
- err = 0;
- -#ifdef target_brcm
- - trx_fixup(outfd, mtd);
- -#endif
- -
- done:
- - close(outfd);
- if (buf)
- free(buf);
- Index: package/mtd/src/libmtd.c
- ===================================================================
- --- package/mtd/src/libmtd.c (revision 0)
- +++ package/mtd/src/libmtd.c (revision 0)
- @@ -0,0 +1,219 @@
- +/*
- + * mtd - simple memory technology device manipulation tool
- + *
- + * Copyright (C) 2005 Waldemar Brodkorb <wbx@dass-it.de>
- + * Copyright (C) 2005-2009 Felix Fietkau <nbd@openwrt.org>
- + * Copyright (C) 2010 Bernhard Loos <bernhardloos@googlemail.com>
- + *
- + * This program is free software; you can redistribute it and/or
- + * modify it under the terms of the GNU General Public License v2
- + * as published by the Free Software Foundation.
- + *
- + * 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.
- + *
- + *
- + * The code is based on the linux-mtd examples.
- + */
- +
- +#include <limits.h>
- +#include <unistd.h>
- +#include <stdlib.h>
- +#include <stdio.h>
- +#include <sys/ioctl.h>
- +#include <fcntl.h>
- +#include <string.h>
- +#include <sys/mman.h>
- +#include <errno.h>
- +
- +#include "mtd.h"
- +
- +#define MULTIPLE_MAX 100
- +
- +struct mtd_device *mtd_open(const char *mtd, bool block)
- +{
- + FILE *fp;
- + char number[3] = { 0 };
- + int flags = O_RDWR | O_SYNC;
- + struct mtd_device *mtddev;
- + char dev[PATH_MAX];
- +
- + mtddev = malloc(sizeof(*mtddev));
- + if (!mtddev) {
- + perror("malloc");
- + exit(1);
- + }
- + memset(mtddev, 0, sizeof(struct mtd_device));
- +
- + fp = fopen("/proc/mtd", "r");
- + if (!fp) {
- + fprintf(stderr, "Can't open /proc/mtd\n");
- + free(mtddev);
- + return NULL;
- + }
- +
- + fscanf(fp, "%*[^\n]\n"); //skip fist line
- +
- + while (fscanf(fp, "mtd%2[0-9]: %x %x \"%20[^\"]\"\n", number, &mtddev->info.size, &mtddev->info.erasesize, dev) == 4) {
- + if (strcmp(dev, mtd) == 0)
- + break;
- + }
- +
- + fclose(fp);
- +
- + mtddev->fd = -1;
- +
- + if (number[0]) {
- + snprintf(dev, sizeof(dev), "/dev/mtd%s/%s", (block ? "block" : ""), number);
- + if ((mtddev->fd = open(dev, flags)) < 0) {
- + snprintf(dev, sizeof(dev), "/dev/mtd%s%s", (block ? "block" : ""), number);
- + mtddev->fd = open(dev, flags);
- + }
- + } else {
- + if (block) {
- + fprintf(stderr, "mtd_open needs a partition name for block mode, not a device\n");
- + free(mtddev);
- + return NULL;
- + }
- + open(mtd, flags);
- + }
- +
- + if(mtddev->fd < 0) {
- + fprintf(stderr, "Could not open mtd device: %s\n", mtd);
- + return NULL;
- + }
- +
- + mtddev->name = mtd;
- +
- + if (block) {
- + mtddev->mmap = mmap(NULL, mtddev->info.erasesize, PROT_READ|PROT_WRITE, MAP_SHARED, mtddev->fd, 0);
- + if (mtddev->mmap == MAP_FAILED) {
- + mtddev->mmap = NULL;
- + perror("mmap");
- + mtd_close(mtddev);
- + return NULL;
- + }
- + } else {
- + if(ioctl(mtddev->fd, MEMGETINFO, &mtddev->info) < 0) {
- + fprintf(stderr, "Could not get MTD device info for %s\n", mtd);
- + mtd_close(mtddev);
- + return NULL;
- + }
- + }
- +
- + return mtddev;
- +}
- +
- +int mtd_unlock(struct mtd_device *mtd)
- +{
- + struct erase_info_user mtdEraseInfo;
- +
- + if (mtd->unlocked)
- + return 0;
- +
- + mtdEraseInfo.start = 0;
- + mtdEraseInfo.length = mtd->info.size;
- + if (ioctl(mtd->fd, MEMUNLOCK, &mtdEraseInfo) < 0) {
- + if (errno != EOPNOTSUPP) {
- + fprintf(stderr, "Failed to unlock %s\n", mtd->name);
- + return -1;
- + }
- + }
- +
- + mtd->unlocked = 1;
- +
- + return 0;
- +}
- +
- +int mtd_erase_block(struct mtd_device *mtd, size_t offset)
- +{
- + struct erase_info_user mtdEraseInfo;
- +
- + mtdEraseInfo.start = offset;
- + mtdEraseInfo.length = mtd->info.erasesize;
- + if (ioctl (mtd->fd, MEMERASE, &mtdEraseInfo) < 0) {
- + fprintf(stderr, "Failed to erase block on %s at 0x%x\n", mtd->name, mtdEraseInfo.start);
- + return -1;
- + }
- +
- + return 0;
- +}
- +
- +int mtd_erase(struct mtd_device *mtd)
- +{
- + size_t pos = 0;
- +
- + while (pos < mtd->info.size) {
- + if (mtd_erase_block(mtd, pos) < 0)
- + return -1;
- +
- + pos += mtd->info.erasesize;
- + }
- + return 0;
- +}
- +
- +void mtd_close(struct mtd_device *mtd)
- +{
- + if (mtd->mmap)
- + munmap(mtd->mmap, mtd->info.erasesize);
- + close(mtd->fd);
- + free(mtd);
- +}
- +
- +struct mtd_device **mtd_open_multiple(const char *mtds)
- +{
- + int count = 0;
- + char *str = strdup(mtds);
- + struct mtd_device *devs[MULTIPLE_MAX];
- + char *next;
- + char *mtd = str;
- + struct mtd_device **ret;
- +
- + do {
- + next = strchr(mtd, ':');
- + if (next) {
- + *next = 0;
- + next++;
- + }
- +
- + devs[count] = mtd_open(mtd, false);
- + if (!devs[count])
- + goto error;
- + count++;
- +
- + mtd = next;
- + } while (next);
- +
- + devs[count] = NULL;
- + count++;
- +
- + ret = malloc(sizeof(struct mtd_device *) * count);
- + memcpy(ret, devs, sizeof(struct mtd_device *) * count);
- +
- + return ret;
- +error:
- + while(count > 0) {
- + --count;
- + mtd_close(devs[count]);
- + }
- + free(str);
- + return NULL;
- +}
- +
- +void mtd_close_multiple(struct mtd_device **mtds)
- +{
- + const char *str = mtds[0]->name;
- + int pos = 0;
- +
- + while(mtds[pos])
- + mtd_close(mtds[pos++]);
- +
- + free((char *) str);
- + free(mtds);
- +}
- Index: package/mtd/src/Makefile
- ===================================================================
- --- package/mtd/src/Makefile (revision 20862)
- +++ package/mtd/src/Makefile (working copy)
- @@ -1,9 +1,10 @@
- CC = gcc
- CFLAGS += -Wall
- -obj = mtd.o jffs2.o crc32.o
- +obj = mtd.o jffs2.o crc32.o libmtd.o
- obj.brcm = trx.o
- obj.brcm47xx = $(obj.brcm)
- +obj.ar71xx = $(obj.brcm)
- ifdef FIS_SUPPORT
- obj += fis.o
- Index: package/mtd/src/trx.c
- ===================================================================
- --- package/mtd/src/trx.c (revision 20862)
- +++ package/mtd/src/trx.c (working copy)
- @@ -3,6 +3,7 @@
- *
- * Copyright (C) 2005 Mike Baker
- * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
- + * Copyright (C) 2010 Bernhard Loos <bernhardloos@googlemail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- @@ -22,17 +23,16 @@
- #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"
- #include "crc32.h"
- +#if __BYTE_ORDER == __BIG_ENDIAN
- +# define STORE32_LE(val) bswap_32(val)
- +#else
- +# define STORE32_LE(val) (val)
- +#endif
- +
- #define TRX_MAGIC 0x30524448 /* "HDR0" */
- struct trx_header {
- unsigned magic; /* "HDR0" */
- @@ -42,91 +42,44 @@
- unsigned offsets[3]; /* Offsets of partitions from start of header */
- };
- -int
- -trx_fixup(int fd, const char *name)
- +static int
- +trx_check(char *imagedata, size_t datalength, size_t mtdlength)
- {
- - 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;
- - }
- +#ifdef TARGET_ar71xx
- + imagedata += 32; /* used on the wrt160nl */
- + datelength -= 32;
- +#endif
- + trx = (struct trx_header *) imagedata;
- - 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;
- - }
- -
- - 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 (trx->magic != STORE32_LE(TRX_MAGIC) || STORE32_LE(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;
- + return -1;
- }
- - /* 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(mtdlength < STORE32_LE(trx->len)) {
- + fprintf(stderr, "Image too big\n");
- + return -1;
- }
- +
- + if (trx->len == STORE32_LE(datalength))
- + return 1;
- - if(mtdsize < trx->len) {
- - fprintf(stderr, "Image too big for partition: %s\n", mtd);
- - close(fd);
- - return 0;
- - }
- + trx->len = STORE32_LE(datalength);
- +
- + trx->crc32 = STORE32_LE(crc32buf((char*) &trx->flag_version, datalength - 3*4));
- + if (quiet < 2)
- + fprintf(stderr, "New crc32: 0x%x\n", trx->crc32);
- - close(fd);
- - return 1;
- + return 0;
- }
- +struct platform_imageops imageops = {
- + .checkimage = trx_check,
- + .firmware_partition = "linux"
- +};
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement