diff options
| author | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2006-02-12 06:00:38 +0000 | 
|---|---|---|
| committer | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2006-02-12 06:00:38 +0000 | 
| commit | 2f3d65dabad91870035f50cd7dc5fcf1f33fd2be (patch) | |
| tree | d604d47ed0783b1cb44ec9a1efb3c5cfb88fc203 /target | |
| parent | 54259a7a47ca4130a5ee7e8172ef4fdab819fd59 (diff) | |
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)
git-svn-id: svn://svn.openwrt.org/openwrt/trunk/openwrt@3221 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target')
| -rw-r--r-- | target/linux/image/ar7/Makefile | 13 | ||||
| -rw-r--r-- | target/linux/image/ar7/sercomm/adam2.bin | bin | 0 -> 131072 bytes | |||
| -rw-r--r-- | target/linux/image/ar7/sercomm/dg834 | bin | 0 -> 80 bytes | |||
| -rw-r--r-- | target/linux/image/ar7/sercomm/jdr454wb | bin | 0 -> 80 bytes | |||
| -rw-r--r-- | target/linux/package/base-files/Makefile | 15 | ||||
| -rwxr-xr-x | target/linux/package/base-files/files/ar7-2.4/etc/init.d/S00adam2 | 8 | ||||
| -rw-r--r-- | target/linux/package/base-files/src/adam2patcher.c | 59 | ||||
| -rw-r--r-- | target/linux/package/base-files/src/jffs2root.c (renamed from target/linux/package/base-files/jffs2root.c) | 0 | ||||
| -rw-r--r-- | target/utils/Makefile | 2 | ||||
| -rw-r--r-- | target/utils/src/dgfirmware.c | 376 | 
10 files changed, 471 insertions, 2 deletions
diff --git a/target/linux/image/ar7/Makefile b/target/linux/image/ar7/Makefile index 38fce6bdf..3a803cbd8 100644 --- a/target/linux/image/ar7/Makefile +++ b/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/target/linux/image/ar7/sercomm/adam2.bin b/target/linux/image/ar7/sercomm/adam2.bin Binary files differnew file mode 100644 index 000000000..d4aa0cd2d --- /dev/null +++ b/target/linux/image/ar7/sercomm/adam2.bin diff --git a/target/linux/image/ar7/sercomm/dg834 b/target/linux/image/ar7/sercomm/dg834 Binary files differnew file mode 100644 index 000000000..61fe336e8 --- /dev/null +++ b/target/linux/image/ar7/sercomm/dg834 diff --git a/target/linux/image/ar7/sercomm/jdr454wb b/target/linux/image/ar7/sercomm/jdr454wb Binary files differnew file mode 100644 index 000000000..821ff1c1a --- /dev/null +++ b/target/linux/image/ar7/sercomm/jdr454wb diff --git a/target/linux/package/base-files/Makefile b/target/linux/package/base-files/Makefile index 637904c2e..cf72eabda 100644 --- a/target/linux/package/base-files/Makefile +++ b/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/target/linux/package/base-files/files/ar7-2.4/etc/init.d/S00adam2 b/target/linux/package/base-files/files/ar7-2.4/etc/init.d/S00adam2 new file mode 100755 index 000000000..0ca4c0145 --- /dev/null +++ b/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/target/linux/package/base-files/src/adam2patcher.c b/target/linux/package/base-files/src/adam2patcher.c new file mode 100644 index 000000000..25a78074a --- /dev/null +++ b/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 <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <unistd.h> +#include <fcntl.h> +#include <stdint.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <string.h> + +#include <sys/ioctl.h> + +int main(int argc, char **argv) +{ +	int fd; +	char *ptr; +	uint32_t *i; + +	if (argc != 2) { +		fprintf(stderr, "Usage: %s <filename>\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/target/linux/package/base-files/jffs2root.c b/target/linux/package/base-files/src/jffs2root.c index 14662fc94..14662fc94 100644 --- a/target/linux/package/base-files/jffs2root.c +++ b/target/linux/package/base-files/src/jffs2root.c diff --git a/target/utils/Makefile b/target/utils/Makefile index 753db53de..5b0f2470b 100644 --- a/target/utils/Makefile +++ b/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/target/utils/src/dgfirmware.c b/target/utils/src/dgfirmware.c new file mode 100644 index 000000000..5ff3b6964 --- /dev/null +++ b/target/utils/src/dgfirmware.c @@ -0,0 +1,376 @@ +#include <stdlib.h> +#include <stdio.h> + + +#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 [<opts>] <img>\n"); +  fprintf(stderr, "  <img>               firmware image filename\n"); +  fprintf(stderr, "  <opts>  -h          print this message\n"); +  fprintf(stderr, "          -f          fix the checksum\n"); +  fprintf(stderr, "          -x  <file>  extract the rootfs file to <file>\n"); +  fprintf(stderr, "          -xk <file>  extract the kernel to <file>\n"); +  fprintf(stderr, "          -m  <file>  merge in rootfs fil\e from <file>\n"); +  fprintf(stderr, "          -k  <file>  merge in kernel from <file>\n"); +  fprintf(stderr, "          -w  <file>  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_START+ROOTFS_SIZE; i++) +    img[i] = 0xff; + +  fp = fopen(fname, "rb"); +  if (fp == NULL) { +    perror(app_name); +    exit(-1); +  } + +  fseek(fp, 0, SEEK_END); +  size = ftell(fp); +   +  if (size > 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_START+KERNEL_SIZE; i++) +    img[i] = 0xff; + +  fp = fopen(fname, "rb"); +  if (fp == NULL) { +    perror(app_name); +    exit(-1); +  } + +  fseek(fp, 0, SEEK_END); +  size = ftell(fp); +   +  if (size > 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; i++) { +    if (!strcmp(argv[i], "-h")) { +      print_usage(); +      return 0; +    } +    else if (!strcmp(argv[i], "-f")) { +      do_fix_checksum = 1; +    } +    else if (!strcmp(argv[i], "-x")) { +      if (i+1 >= 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; +} +  | 
