From 86382b98a47616d0ac75e336381c4d27bc88e69f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 12 Feb 2006 06:00:38 +0000 Subject: [PATCH] add support for netgear dg834 and the almost identical sphairon jdr454wb: new images, automatic boot loader patcher, updated flash script (dlink.pl renamed to adam2flash.pl) - Thanks to Jonathan McDowell (Noodles) SVN-Revision: 3221 --- openwrt/scripts/{dlink.pl => adam2flash.pl} | 13 +- openwrt/target/linux/image/ar7/Makefile | 13 + .../target/linux/image/ar7/sercomm/adam2.bin | Bin 0 -> 131072 bytes openwrt/target/linux/image/ar7/sercomm/dg834 | Bin 0 -> 80 bytes .../target/linux/image/ar7/sercomm/jdr454wb | Bin 0 -> 80 bytes .../target/linux/package/base-files/Makefile | 15 +- .../files/ar7-2.4/etc/init.d/S00adam2 | 8 + .../package/base-files/src/adam2patcher.c | 59 +++ .../package/base-files/{ => src}/jffs2root.c | 0 openwrt/target/utils/Makefile | 2 +- openwrt/target/utils/src/dgfirmware.c | 376 ++++++++++++++++++ 11 files changed, 481 insertions(+), 5 deletions(-) rename openwrt/scripts/{dlink.pl => adam2flash.pl} (95%) create mode 100644 openwrt/target/linux/image/ar7/sercomm/adam2.bin create mode 100644 openwrt/target/linux/image/ar7/sercomm/dg834 create mode 100644 openwrt/target/linux/image/ar7/sercomm/jdr454wb create mode 100755 openwrt/target/linux/package/base-files/files/ar7-2.4/etc/init.d/S00adam2 create mode 100644 openwrt/target/linux/package/base-files/src/adam2patcher.c rename openwrt/target/linux/package/base-files/{ => src}/jffs2root.c (100%) create mode 100644 openwrt/target/utils/src/dgfirmware.c diff --git a/openwrt/scripts/dlink.pl b/openwrt/scripts/adam2flash.pl similarity index 95% rename from openwrt/scripts/dlink.pl rename to openwrt/scripts/adam2flash.pl index ace6476e92..bd0fa69a61 100755 --- a/openwrt/scripts/dlink.pl +++ b/openwrt/scripts/adam2flash.pl @@ -39,20 +39,27 @@ my $probe = IO::Socket::INET->new(Proto => 'udp', my $setip = unpack("N", inet_aton($ip)); $setip > 0 or usage(); +my @packets; +foreach my $ver ([18, 1], [22, 2]) { + push @packets, pack("vCCVNV", 0, @$ver, 1, $setip, 0); +} print STDERR "Looking for device: "; -my $packet = pack("vCCVNV", 0, 22, 2, 1, $setip, 0); my $broadcast = sockaddr_in(5035, INADDR_BROADCAST); my $scanning; my $box; $SIG{"ALRM"} = sub { return if --$scanning <= 0; - $probe->send($packet, 0, $broadcast); + foreach my $packet (@packets) { + $probe->send($packet, 0, $broadcast); + } print STDERR "."; }; $scanning = 10; -$probe->send($packet, 0, $broadcast); +foreach my $packet (@packets) { + $probe->send($packet, 0, $broadcast); +} print STDERR "."; while($scanning) { diff --git a/openwrt/target/linux/image/ar7/Makefile b/openwrt/target/linux/image/ar7/Makefile index 38fce6bdfc..3a803cbd8b 100644 --- a/openwrt/target/linux/image/ar7/Makefile +++ b/openwrt/target/linux/image/ar7/Makefile @@ -83,6 +83,19 @@ $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-$(FS)-$(1).bin: $(BIN_DIR)/openwrt-$(BOARD install: $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-$(FS)-$(1).bin endef +define sercomm_template +$(BIN_DIR)/openwrt-$(1)-$(KERNEL)-$(FS).bin: $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-$(FS).bin + cat sercomm/adam2.bin "$$^" > "$$@.tmp" + dd if=sercomm/$(1) of="$$@.tmp" bs=$$$$((0x3e0000 - 80)) seek=1 conv=notrunc + $(STAGING_DIR)/bin/dgfirmware -f -w "$$@" "$$@.tmp" + rm -f "$$@.tmp" + +install: $(BIN_DIR)/openwrt-$(1)-$(KERNEL)-$(FS).bin +endef + +$(eval $(call sercomm_template,dg834)) +$(eval $(call sercomm_template,jdr454wb)) + $(eval $(call pattern_template,AG1B)) $(eval $(call pattern_template,WA22)) $(eval $(call pattern_template,WAG2)) diff --git a/openwrt/target/linux/image/ar7/sercomm/adam2.bin b/openwrt/target/linux/image/ar7/sercomm/adam2.bin new file mode 100644 index 0000000000000000000000000000000000000000..d4aa0cd2d38de53eeb55c527e37dc26fc3cfd2f9 GIT binary patch literal 131072 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 literal 0 HcmV?d00001 diff --git a/openwrt/target/linux/image/ar7/sercomm/dg834 b/openwrt/target/linux/image/ar7/sercomm/dg834 new file mode 100644 index 0000000000000000000000000000000000000000..61fe336e85b7e2143528eba9026a997b0d4cb7af GIT binary patch literal 80 tcmezWzu2|NIo~&z0SH{&EsRY-44lA`!Q2QYX($O|LACz}0?o$%{{aP>5A6T| literal 0 HcmV?d00001 diff --git a/openwrt/target/linux/image/ar7/sercomm/jdr454wb b/openwrt/target/linux/image/ar7/sercomm/jdr454wb new file mode 100644 index 0000000000000000000000000000000000000000..821ff1c1afbdb456faa42ec9631b757692360adb GIT binary patch literal 80 tcmezWzu2|NIo~&z0SG(;EDX#*44lA;!N33}>A(tNLACz}0u{^u{{aTX51;@5 literal 0 HcmV?d00001 diff --git a/openwrt/target/linux/package/base-files/Makefile b/openwrt/target/linux/package/base-files/Makefile index 637904c2e8..cf72eabdac 100644 --- a/openwrt/target/linux/package/base-files/Makefile +++ b/openwrt/target/linux/package/base-files/Makefile @@ -15,8 +15,21 @@ $(PKG_BUILD_DIR)/.prepared: mkdir -p $(PKG_BUILD_DIR) touch $@ +ifeq ($(BOARD),ar7) +$(PKG_BUILD_DIR)/adam2patcher: src/adam2patcher.c + $(TARGET_CC) -o $@ $< + +$(PKG_BUILD_DIR)/.built: $(PKG_BUILD_DIR)/adam2patcher + +$(IDIR_OPENWRT)/sbin/adam2patcher: $(PKG_BUILD_DIR)/adam2patcher + mkdir -p $(IDIR_OPENWRT)/sbin + $(CP) $(PKG_BUILD_DIR)/adam2patcher $(IDIR_OPENWRT)/sbin + +$(IPKG_OPENWRT): $(IDIR_OPENWRT)/sbin/adam2patcher +endif + ifeq ($(BOARD),brcm) -$(PKG_BUILD_DIR)/jffs2root: jffs2root.c +$(PKG_BUILD_DIR)/jffs2root: src/jffs2root.c $(TARGET_CC) -o $@ $< $(PKG_BUILD_DIR)/.built: $(PKG_BUILD_DIR)/jffs2root diff --git a/openwrt/target/linux/package/base-files/files/ar7-2.4/etc/init.d/S00adam2 b/openwrt/target/linux/package/base-files/files/ar7-2.4/etc/init.d/S00adam2 new file mode 100755 index 0000000000..0ca4c01453 --- /dev/null +++ b/openwrt/target/linux/package/base-files/files/ar7-2.4/etc/init.d/S00adam2 @@ -0,0 +1,8 @@ +#!/bin/sh +# ADAM2 patcher for Netgear DG834 and compatible +MD5="$(md5sum /dev/mtdblock/0 | awk '{print $1}')" +[ "$MD5" = "0530bfdf00ec155f4182afd70da028c1" ] && { + mtd unlock adam2 + /sbin/adam2patcher /dev/mtdblock/0 +} +rm -f /etc/init.d/S00adam2 /sbin/adam2patcher >&- 2>&- diff --git a/openwrt/target/linux/package/base-files/src/adam2patcher.c b/openwrt/target/linux/package/base-files/src/adam2patcher.c new file mode 100644 index 0000000000..25a78074a6 --- /dev/null +++ b/openwrt/target/linux/package/base-files/src/adam2patcher.c @@ -0,0 +1,59 @@ +/* + * patcher.c - ADAM2 patcher for Netgear DG834 (and compatible) + * + * Copyright (C) 2006 Felix Fietkau + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +int main(int argc, char **argv) +{ + int fd; + char *ptr; + uint32_t *i; + + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(1); + } + + if (((fd = open(argv[1], O_RDWR)) < 0) + || ((ptr = mmap(0, 128 * 1024, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == (void *) (-1))) { + fprintf(stderr, "Can't open file\n"); + exit(1); + } + + i = (uint32_t *) &ptr[0x3944]; + if (*i == 0x0c000944) { + fprintf(stderr, "Unpatched ADAM2 detected. Patching... "); + *i = 0x00000000; + msync(i, sizeof(*i), MS_SYNC|MS_INVALIDATE); + fprintf(stderr, "done!\n"); + } else if (*i == 0x00000000) { + fprintf(stderr, "Patched ADAM2 detected.\n"); + } else { + fprintf(stderr, "Unknown ADAM2 detected. Can't patch!\n"); + } + + close(fd); +} diff --git a/openwrt/target/linux/package/base-files/jffs2root.c b/openwrt/target/linux/package/base-files/src/jffs2root.c similarity index 100% rename from openwrt/target/linux/package/base-files/jffs2root.c rename to openwrt/target/linux/package/base-files/src/jffs2root.c diff --git a/openwrt/target/utils/Makefile b/openwrt/target/utils/Makefile index 753db53deb..5b0f2470b4 100644 --- a/openwrt/target/utils/Makefile +++ b/openwrt/target/utils/Makefile @@ -1,6 +1,6 @@ include $(TOPDIR)/rules.mk -TARGETS := addpattern trx motorola-bin +TARGETS := addpattern trx motorola-bin dgfirmware UTILS_BUILD_DIR:=$(BUILD_DIR)/target-utils diff --git a/openwrt/target/utils/src/dgfirmware.c b/openwrt/target/utils/src/dgfirmware.c new file mode 100644 index 0000000000..5ff3b69646 --- /dev/null +++ b/openwrt/target/utils/src/dgfirmware.c @@ -0,0 +1,376 @@ +#include +#include + + +#define IMG_SIZE 0x3e0000 + +#define KERNEL_START 0x020000 +#define KERNEL_SIZE 0x0b0000 + +#define ROOTFS_START 0x0d0000 +#define ROOTFS_SIZE 0x30ffb2 + +char* app_name; + + + + +void print_usage(void) +{ + fprintf(stderr, "usage: dgfirmware [] \n"); + fprintf(stderr, " firmware image filename\n"); + fprintf(stderr, " -h print this message\n"); + fprintf(stderr, " -f fix the checksum\n"); + fprintf(stderr, " -x extract the rootfs file to \n"); + fprintf(stderr, " -xk extract the kernel to \n"); + fprintf(stderr, " -m merge in rootfs fil\e from \n"); + fprintf(stderr, " -k merge in kernel from \n"); + fprintf(stderr, " -w write back the modified firmware\n"); +} + + +unsigned char* read_img(const char *fname) +{ + FILE *fp; + int size; + unsigned char *img; + + fp = fopen(fname, "rb"); + if (fp == NULL) { + perror(app_name); + exit(-1); + } + + fseek(fp, 0, SEEK_END); + size = ftell(fp); + + if (size != IMG_SIZE) { + fprintf(stderr, "%s: image file has wrong size\n", app_name); + fclose(fp); + exit(-1); + } + + rewind(fp); + + img = malloc(IMG_SIZE); + if (img == NULL) { + perror(app_name); + fclose(fp); + exit(-1); + } + + if (fread(img, 1, IMG_SIZE, fp) != IMG_SIZE) { + fprintf(stderr, "%s: can't read image file\n", app_name); + fclose(fp); + exit(-1); + } + + fclose(fp); + return img; +} + + +void write_img(unsigned char* img, const char *fname) +{ + FILE *fp; + + fp = fopen(fname, "wb"); + if (fp == NULL) { + perror(app_name); + exit(-1); + } + + if (fwrite(img, 1, IMG_SIZE, fp) != IMG_SIZE) { + fprintf(stderr, "%s: can't write image file\n", app_name); + fclose(fp); + exit(-1); + } +} + + +void write_rootfs(unsigned char* img, const char *fname) +{ + FILE *fp; + + fp = fopen(fname, "wb"); + if (fp == NULL) { + perror(app_name); + exit(-1); + } + + if (fwrite(img+ROOTFS_START, 1, ROOTFS_SIZE, fp) != ROOTFS_SIZE) { + fprintf(stderr, "%s: can't write image file\n", app_name); + fclose(fp); + exit(-1); + } +} + + +void write_kernel(unsigned char* img, const char *fname) +{ + FILE *fp; + + fp = fopen(fname, "wb"); + if (fp == NULL) { + perror(app_name); + exit(-1); + } + + if (fwrite(img+KERNEL_START, 1, KERNEL_SIZE, fp) != KERNEL_SIZE) { + fprintf(stderr, "%s: can't write kernel file\n", app_name); + fclose(fp); + exit(-1); + } +} + + +unsigned char* read_rootfs(unsigned char* img, const char *fname) +{ + FILE *fp; + int size; + int i; + + for (i=ROOTFS_START; i ROOTFS_SIZE) { + fprintf(stderr, "%s: rootfs image file is too big\n", app_name); + fclose(fp); + exit(-1); + } + + rewind(fp); + + if (fread(img+ROOTFS_START, 1, size, fp) != size) { + fprintf(stderr, "%s: can't read rootfs image file\n", app_name); + fclose(fp); + exit(-1); + } + + fclose(fp); + return img; +} + + +unsigned char* read_kernel(unsigned char* img, const char *fname) +{ + FILE *fp; + int size; + int i; + + for (i=KERNEL_START; i KERNEL_SIZE) { + fprintf(stderr, "%s: kernel binary file is too big\n", app_name); + fclose(fp); + exit(-1); + } + + rewind(fp); + + if (fread(img+KERNEL_START, 1, size, fp) != size) { + fprintf(stderr, "%s: can't read kernel file\n", app_name); + fclose(fp); + exit(-1); + } + + fclose(fp); + return img; +} + + +int get_checksum(unsigned char* img) +{ + short unsigned s; + + s = img[0x3dfffc] + (img[0x3dfffd]<<8); + + return s; +} + + +void set_checksum(unsigned char*img, unsigned short sum) +{ + img[0x3dfffc] = sum & 0xff; + img[0x3dfffd] = (sum>>8) & 0xff; +} + + +int compute_checksum(unsigned char* img) +{ + int i; + short s=0; + + for (i=0; i<0x3dfffc; i++) + s += img[i]; + + return s; +} + + +int main(int argc, char* argv[]) +{ + char *img_fname = NULL; + char *rootfs_fname = NULL; + char *kernel_fname = NULL; + char *new_img_fname = NULL; + + int do_fix_checksum = 0; + int do_write = 0; + int do_write_rootfs = 0; + int do_read_rootfs = 0; + int do_write_kernel = 0; + int do_read_kernel = 0; + + int i; + unsigned char *img; + unsigned short img_checksum; + unsigned short real_checksum; + + app_name = argv[0]; + + for (i=1; i= argc) { + fprintf(stderr, "%s: missing argument\n", app_name); + return -1; + } + do_write_rootfs = 1; + rootfs_fname = argv[i+1]; + i++; + } + else if (!strcmp(argv[i], "-xk")) { + if (i+1 >= argc) { + fprintf(stderr, "%s: missing argument\n", app_name); + return -1; + } + do_write_kernel = 1; + kernel_fname = argv[i+1]; + i++; + } + else if (!strcmp(argv[i], "-m")) { + if (i+1 >= argc) { + fprintf(stderr, "%s: missing argument\n", app_name); + return -1; + } + do_read_rootfs = 1; + rootfs_fname = argv[i+1]; + i++; + } + else if (!strcmp(argv[i], "-k")) { + if (i+1 >= argc) { + fprintf(stderr, "%s: missing argument\n", app_name); + return -1; + } + do_read_kernel = 1; + kernel_fname = argv[i+1]; + i++; + } + else if (!strcmp(argv[i], "-w")) { + if (i+1 >= argc) { + fprintf(stderr, "%s: missing argument\n", app_name); + return -1; + } + do_write = 1; + new_img_fname = argv[i+1]; + i++; + } + else if (img_fname != 0) { + fprintf(stderr, "%s: too many arguments\n", app_name); + return -1; + } + else { + img_fname = argv[i]; + } + } + + if (img_fname == NULL) { + fprintf(stderr, "%s: missing argument\n", app_name); + return -1; + } + + if ((do_read_rootfs && do_write_rootfs) || + (do_read_kernel && do_write_kernel)) { + fprintf(stderr, "%s: conflictuous options\n", app_name); + return -1; + } + + printf ("** Read firmware file\n"); + img = read_img(img_fname); + + printf ("Firmware product: %s\n", img+0x3dffbd); + printf ("Firmware version: 1.%02d.%02d\n", (img[0x3dffeb] & 0x7f), img[0x3dffec]); + + if (do_write_rootfs) { + printf ("** Write rootfs file\n"); + write_rootfs(img, rootfs_fname); + } + + if (do_write_kernel) { + printf ("** Write kernel file\n"); + write_kernel(img, kernel_fname); + } + + if (do_read_rootfs) { + printf ("** Read rootfs file\n"); + read_rootfs(img, rootfs_fname); + do_fix_checksum = 1; + } + + if (do_read_kernel) { + printf ("** Read kernel file\n"); + read_kernel(img, kernel_fname); + do_fix_checksum = 1; + } + + img_checksum = get_checksum(img); + real_checksum = compute_checksum(img); + + printf ("image checksum = %04x\n", img_checksum); + printf ("real checksum = %04x\n", real_checksum); + + if (do_fix_checksum) { + if (img_checksum != real_checksum) { + printf ("** Bad Checksum, fix it\n"); + set_checksum(img, real_checksum); + } + else { + printf ("** Checksum is correct, good\n"); + } + } + + if (do_write) { + printf ("** Write image file\n"); + write_img(img, new_img_fname); + } + + free(img); + return 0; +} + -- 2.30.2