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
This commit is contained in:
parent
ec41db56e7
commit
86382b98a4
11 changed files with 481 additions and 5 deletions
|
@ -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) {
|
|
@ -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))
|
||||
|
|
BIN
openwrt/target/linux/image/ar7/sercomm/adam2.bin
Normal file
BIN
openwrt/target/linux/image/ar7/sercomm/adam2.bin
Normal file
Binary file not shown.
BIN
openwrt/target/linux/image/ar7/sercomm/dg834
Normal file
BIN
openwrt/target/linux/image/ar7/sercomm/dg834
Normal file
Binary file not shown.
BIN
openwrt/target/linux/image/ar7/sercomm/jdr454wb
Normal file
BIN
openwrt/target/linux/image/ar7/sercomm/jdr454wb
Normal file
Binary file not shown.
|
@ -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
|
||||
|
|
|
@ -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>&-
|
59
openwrt/target/linux/package/base-files/src/adam2patcher.c
Normal file
59
openwrt/target/linux/package/base-files/src/adam2patcher.c
Normal file
|
@ -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);
|
||||
}
|
|
@ -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
|
||||
|
||||
|
|
376
openwrt/target/utils/src/dgfirmware.c
Normal file
376
openwrt/target/utils/src/dgfirmware.c
Normal file
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in a new issue