diff options
-rw-r--r-- | package/openwrt/Config.in | 0 | ||||
-rw-r--r-- | package/openwrt/Makefile.in | 1 | ||||
-rw-r--r-- | package/openwrt/mtd.c | 252 | ||||
-rw-r--r-- | package/openwrt/openwrt.mk | 94 |
4 files changed, 347 insertions, 0 deletions
diff --git a/package/openwrt/Config.in b/package/openwrt/Config.in new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/package/openwrt/Config.in diff --git a/package/openwrt/Makefile.in b/package/openwrt/Makefile.in new file mode 100644 index 0000000000..5843057b1a --- /dev/null +++ b/package/openwrt/Makefile.in @@ -0,0 +1 @@ +TARGETS+=openwrt diff --git a/package/openwrt/mtd.c b/package/openwrt/mtd.c new file mode 100644 index 0000000000..ff104c6575 --- /dev/null +++ b/package/openwrt/mtd.c @@ -0,0 +1,252 @@ +/* + * mtd.c + * + * Copyright (C) 2005 Waldemar Brodkorb + * + * $Id$ + * + * 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. + * + * mtd utility for the openwrt project + * it is mainly code from the linux-mtd project, which accepts the same + * command line arguments as the broadcom utility + * + */ + +#include <limits.h> +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <stdint.h> +#include <fcntl.h> +#include <errno.h> +#include <error.h> +#include <time.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/param.h> +#include <sys/mount.h> +#include <sys/stat.h> +#include <string.h> + +#include <linux/mtd/mtd.h> + +/* trx header */ +#define TRX_MAGIC 0x30524448 /* "HDR0" */ +#define TRX_VERSION 1 +#define TRX_MAX_LEN 0x3A0000 +#define TRX_NO_HEADER 1 /* Do not write TRX header */ + +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 */ +}; + +#define BUFSIZE (10 * 1024) + +extern int mtd_open(const char *mtd, int flags); +extern int mtd_erase(const char *mtd); +extern int mtd_write(const char *trxfile, const char *mtd); + +int +mtd_unlock(const char *mtd) +{ + int fd; + struct mtd_info_user mtdInfo; + struct erase_info_user mtdLockInfo; + + fd = mtd_open(mtd, O_RDWR); + if(fd < 0) { + fprintf(stderr, "Could not open mtd device: %s\n", mtd); + exit(1); + } + + if(ioctl(fd, MEMGETINFO, &mtdInfo)) { + fprintf(stderr, "Could not get MTD device info from %s\n", mtd); + close(fd); + exit(1); + } + + mtdLockInfo.start = 0; + mtdLockInfo.length = mtdInfo.size; + if(ioctl(fd, MEMUNLOCK, &mtdLockInfo)) { + fprintf(stderr, "Could not unlock MTD device: %s\n", mtd); + close(fd); + exit(1); + } + + close(fd); + return 0; +} + +int +mtd_open(const char *mtd, int flags) +{ + FILE *fp; + char dev[PATH_MAX]; + int i; + + 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); + fclose(fp); + return open(dev, flags); + } + } + fclose(fp); + } + + return open(mtd, flags); +} + +int +mtd_erase(const char *mtd) +{ + int fd; + struct mtd_info_user mtdInfo; + struct erase_info_user mtdEraseInfo; + + fd = mtd_open(mtd, O_RDWR); + if(fd < 0) { + fprintf(stderr, "Could not open mtd device: %s\n", mtd); + exit(1); + } + + if(ioctl(fd, MEMGETINFO, &mtdInfo)) { + fprintf(stderr, "Could not get MTD device info from %s\n", mtd); + close(fd); + exit(1); + } + + mtdEraseInfo.length = mtdInfo.erasesize; + + for (mtdEraseInfo.start = 0; + mtdEraseInfo.start < mtdInfo.size; + mtdEraseInfo.start += mtdInfo.erasesize) { + + if(ioctl(fd, MEMUNLOCK, &mtdEraseInfo)) { + fprintf(stderr, "Could not unlock MTD device: %s\n", mtd); + close(fd); + exit(1); + } + if(ioctl(fd, MEMERASE, &mtdEraseInfo)) { + fprintf(stderr, "Could not erase MTD device: %s\n", mtd); + close(fd); + exit(1); + } + } + + close(fd); + return 0; + +} + +int +mtd_write(const char *trxfile, const char *mtd) +{ + int fd; + int trxfd; + int i; + size_t result,size,written; + struct mtd_info_user mtdInfo; + struct erase_info_user mtdEraseInfo; + struct stat trxstat; + unsigned char src[BUFSIZE],dest[BUFSIZE]; + + fd = mtd_open(mtd, O_RDWR); + if(fd < 0) { + fprintf(stderr, "Could not open mtd device: %s\n", mtd); + exit(1); + } + + if(ioctl(fd, MEMGETINFO, &mtdInfo)) { + fprintf(stderr, "Could not get MTD device info from %s\n", mtd); + close(fd); + exit(1); + } + + trxfd = open(trxfile,O_RDONLY); + if(trxfd < 0) { + fprintf(stderr, "Could not open trx image: %s\n", trxfile); + exit(1); + } + + if (fstat (trxfd,&trxstat) < 0) { + fprintf(stderr, "Could not get trx image file status: %s\n", trxfile); + close(trxfd); + exit(1); + } + + if(mtdInfo.size < trxstat.st_size) { + fprintf(stderr, "image to big for mtd partition: %s\n", mtd); + close(trxfd); + exit(1); + } + + mtdEraseInfo.start = 0; + mtdEraseInfo.length = trxstat.st_size & ~(mtdInfo.erasesize -1); + if(trxstat.st_size % mtdInfo.erasesize) mtdEraseInfo.length += mtdInfo.erasesize; + + /* erase the chunk */ + if (ioctl (fd,MEMERASE,&mtdEraseInfo) < 0) { + fprintf(stderr, "erasing mtd failed: %s\n", mtd); + exit(1); + } + + size = trxstat.st_size; + i = BUFSIZE; + written = 0; + + while (size) { + if (size < BUFSIZE) i = size; + read(trxfd,src,i); + result = write(fd,src,i); + if (i != result) { + if (result < 0) { + fprintf(stderr,"error while writing image"); + exit(1); + } + fprintf(stderr,"error writing image"); + exit(1); + } + written += i; + size -= i; + } + + return 0; +} + +int main(int argc, char **argv) { + if(argc == 3 && strcasecmp(argv[1],"unlock")==0) { + printf("Unlocking %s\n",argv[2]); + return mtd_unlock(argv[2]); + } + if(argc == 3 && strcasecmp(argv[1],"erase")==0) { + printf("Erasing %s\n",argv[2]); + return mtd_erase(argv[2]); + } + if(argc == 4 && strcasecmp(argv[1],"write")==0) { + printf("Writing %s to %s\n",argv[2],argv[3]); + return mtd_write(argv[2],argv[3]); + } + + printf("no valid command given\n"); + return -1; +} + diff --git a/package/openwrt/openwrt.mk b/package/openwrt/openwrt.mk new file mode 100644 index 0000000000..d58a367f12 --- /dev/null +++ b/package/openwrt/openwrt.mk @@ -0,0 +1,94 @@ +############################################################# +# +# openwrt tools +# +############################################################# + +OPENWRT_SITE=http://openwrt.openbsd-geek.de + +# shared library +OPENWRT_SHARED_SOURCE=openwrt-shared.tar.gz +OPENWRT_SHARED_DIR=$(BUILD_DIR)/openwrt-shared +OPENWRT_SHARED_TARGET_BINARY:=usr/lib/libshared.so + +$(DL_DIR)/$(OPENWRT_SHARED_SOURCE): + $(WGET) -P $(DL_DIR) $(OPENWRT_SITE)/$(OPENWRT_SHARED_SOURCE) + +$(OPENWRT_SHARED_DIR)/.source: $(DL_DIR)/$(OPENWRT_SHARED_SOURCE) + zcat $(DL_DIR)/$(OPENWRT_SHARED_SOURCE) | tar -C $(BUILD_DIR) $(TAR_OPTIONS) - + touch $(OPENWRT_SHARED_DIR)/.source + +$(TARGET_DIR)/$(OPENWRT_SHARED_TARGET_BINARY): $(OPENWRT_SHARED_DIR)/.source + $(MAKE) -C $(OPENWRT_SHARED_DIR) -f Makefile-openwrt \ + INSTALLDIR=$(TARGET_DIR) \ + CC=$(TARGET_CC) LD=$(TARGET_CROSS)ld STRIP="$(STRIP)" \ + CFLAGS="$(TARGET_CFLAGS) -I. -I../binary/include -Wall -I$(OPENWRT_SRCBASE)/" \ + install + +openwrt-shared: $(TARGET_DIR)/$(OPENWRT_SHARED_TARGET_BINARY) + +openwrt-shared-clean: + -$(MAKE) -C $(OPENWRT_SHARED_DIR) clean + + +# nvram tool +OPENWRT_NVRAM_SOURCE=openwrt-nvram.tar.gz +OPENWRT_NVRAM_DIR=$(BUILD_DIR)/openwrt-nvram +OPENWRT_NVRAM_TARGET_BINARY:=usr/sbin/nvram + +$(DL_DIR)/$(OPENWRT_NVRAM_SOURCE): + $(WGET) -P $(DL_DIR) $(OPENWRT_SITE)/$(OPENWRT_NVRAM_SOURCE) + +$(OPENWRT_NVRAM_DIR)/.source: $(DL_DIR)/$(OPENWRT_NVRAM_SOURCE) + zcat $(DL_DIR)/$(OPENWRT_NVRAM_SOURCE) | tar -C $(BUILD_DIR) $(TAR_OPTIONS) - + touch $(OPENWRT_NVRAM_DIR)/.source + +$(TARGET_DIR)/$(OPENWRT_NVRAM_TARGET_BINARY): $(OPENWRT_NVRAM_DIR)/.source + $(MAKE) -C $(OPENWRT_NVRAM_DIR) INSTALLDIR=$(TARGET_DIR) \ + CC=$(TARGET_CC) LD=$(TARGET_CROSS)ld STRIP="$(STRIP)" \ + CFLAGS="$(TARGET_CFLAGS) -I. -I../binary/include -Wall -DOPENWRT_NVRAM" \ + install + +openwrt-nvram: $(TARGET_DIR)/$(OPENWRT_NVRAM_TARGET_BINARY) + +openwrt-nvram-clean: + -$(MAKE) -C $(OPENWRT_NVRAM_BUILD_DIR) clean + +# mtd tool +OPENWRT_MTD_SOURCE=package/openwrt/mtd.c +OPENWRT_MTD_TARGET_BINARY:=sbin/mtd + +$(TARGET_DIR)/$(OPENWRT_MTD_TARGET_BINARY): + $(TARGET_CC) -o $(TARGET_DIR)/$(OPENWRT_MTD_TARGET_BINARY) $(OPENWRT_MTD_SOURCE) + +openwrt-mtd: $(TARGET_DIR)/$(OPENWRT_MTD_TARGET_BINARY) + +# wlconf tool +OPENWRT_WLCONF_SOURCE=openwrt-wlconf.tar.gz +OPENWRT_WLCONF_DIR=$(BUILD_DIR)/openwrt-wlconf +OPENWRT_WLCONF_TARGET_BINARY:=usr/sbin/wlconf + +$(DL_DIR)/$(OPENWRT_WLCONF_SOURCE): + $(WGET) -P $(DL_DIR) $(OPENWRT_SITE)/$(OPENWRT_WLCONF_SOURCE) + +$(OPENWRT_WLCONF_DIR)/.source: $(DL_DIR)/$(OPENWRT_WLCONF_SOURCE) + zcat $(DL_DIR)/$(OPENWRT_WLCONF_SOURCE) | tar -C $(BUILD_DIR) $(TAR_OPTIONS) - + touch $(OPENWRT_WLCONF_DIR)/.source + +$(TARGET_DIR)/$(OPENWRT_WLCONF_TARGET_BINARY): $(OPENWRT_WLCONF_DIR)/.source + $(MAKE) -C $(OPENWRT_WLCONF_DIR) INSTALLDIR=$(TARGET_DIR) \ + CC=$(TARGET_CC) LD=$(TARGET_CROSS)ld STRIP="$(STRIP)" \ + CFLAGS="$(TARGET_CFLAGS) -I. -I../binary/include -I$(BUILD_DIR)/openwrt-shared \ + -I$(BUILD_DIR)/openwrt-nvram -Wall -DOPENWRT_WLCONF" \ + LDFLAGS="-lnvram -lshared -L$(BUILD_DIR)/openwrt-shared -L$(BUILD_DIR)/openwrt-nvram" \ + install + +openwrt-wlconf: $(TARGET_DIR)/$(OPENWRT_WLCONF_TARGET_BINARY) + +openwrt-wlconf-clean: + -$(MAKE) -C $(OPENWRT_WLCONF_BUILD_DIR) clean + + +openwrt: openwrt-shared openwrt-nvram openwrt-mtd openwrt-wlconf + + |