lantiq: DGN3500 (all known variants) factory and sysupgrade image building support
This patch adds factory image building for the DGN3500, all variants, and fixes sysupgrade images to make them play nice with the sercomm secondary boot loader. The factory images can be used directly in the update dialog in the interface of the stock firmware and via the special Sercomm bootmode and a special windows flashing utility (allegedly present in the CD that came with the device -- but it's also compatible with the NSLU2 Upgrade_207_XP utility.) The special bootmode can be activated by turning the device on while holding the reset button pressed, then releasing it when the power led starts blinking red and green. Please notice that if using the 207 utility, it will always report that the flashing failed even though it completed successfully. Just power cycle the router manually after the utility reports the failure and OpenWRT will boot. This same utility (despite reporting failure in this case too) can revert a DGN3500 (any variant) to the appropriate stock Netgear firmware. This patch is a heavily modified version of a package I found on the OpenWRT forum with a couple fixes and features added -- mainly the generation of all the different image variants to support all known models directly, atm known variants are AnnexA-WW, AnnexA-NA and AnnexB-DE/GR. I tested the patch successfully on my device. Signed-off-by: Marco Antonio Mauro <marcus90@gmail.com> SVN-Revision: 41236
This commit is contained in:
parent
9bbbcf60b3
commit
575127fe1c
3 changed files with 208 additions and 3 deletions
|
@ -83,6 +83,43 @@ define Image/Build/squashfs
|
||||||
$(if $(3),$(call MkBrnImage,$(3),$(4),$(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(3)-brnImage,$(2),$(1),$(5)))
|
$(if $(3),$(call MkBrnImage,$(3),$(4),$(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(3)-brnImage,$(2),$(1),$(5)))
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
DGN3500_SKERNEL=0x50000
|
||||||
|
DGN3500_SKERNEL_DECIMAL=327680
|
||||||
|
define Image/BuildDGN3500/squashfs
|
||||||
|
dd if=/dev/zero of=$(BIN_DIR)/$(IMG_PREFIX)-pad bs=$(DGN3500_SKERNEL_DECIMAL) count=1
|
||||||
|
cat $(BIN_DIR)/$(IMG_PREFIX)-pad $(KDIR)/uImage-$(2) $(KDIR)/root.$(1) > $(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory-prepad.img
|
||||||
|
rm -r $(BIN_DIR)/$(IMG_PREFIX)-pad
|
||||||
|
dd if=/dev/zero ibs=16M count=1 | tr "\000" "\377" > $(BIN_DIR)/$(IMG_PREFIX)-pwf
|
||||||
|
cp $(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory-prepad.img $(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory-prepadNA.img
|
||||||
|
dgn3500sum $(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory-prepadNA.img $(DGN3500_SKERNEL) NA
|
||||||
|
$(call prepare_generic_squashfs,$(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory-prepadNA.img)
|
||||||
|
cp $(BIN_DIR)/$(IMG_PREFIX)-pwf $(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory-NA.img
|
||||||
|
dd if=$(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory-prepadNA.img of=$(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory-NA.img conv=notrunc
|
||||||
|
dd if=$(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory-prepadNA.img of=$(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-sysupgrade-NA.image bs=$(DGN3500_SKERNEL_DECIMAL) skip=1
|
||||||
|
rm -r $(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory-prepadNA.img
|
||||||
|
mv $(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory-prepad.img $(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory-prepadWW.img
|
||||||
|
dgn3500sum $(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory-prepadWW.img $(DGN3500_SKERNEL) WW
|
||||||
|
$(call prepare_generic_squashfs,$(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory-prepadWW.img)
|
||||||
|
mv $(BIN_DIR)/$(IMG_PREFIX)-pwf $(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory-WW.img
|
||||||
|
dd if=$(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory-prepadWW.img of=$(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory-WW.img conv=notrunc
|
||||||
|
dd if=$(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory-prepadWW.img of=$(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-sysupgrade-WW.image bs=$(DGN3500_SKERNEL_DECIMAL) skip=1
|
||||||
|
rm -r $(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory-prepadWW.img
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Image/BuildDGN3500B/squashfs
|
||||||
|
dd if=/dev/zero of=$(BIN_DIR)/$(IMG_PREFIX)-pad bs=327680 count=1
|
||||||
|
cat $(BIN_DIR)/$(IMG_PREFIX)-pad $(KDIR)/uImage-$(2) $(KDIR)/root.$(1) > $(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory-prepad.img
|
||||||
|
rm -r $(BIN_DIR)/$(IMG_PREFIX)-pad
|
||||||
|
dd if=/dev/zero ibs=16M count=1 | tr "\000" "\377" > $(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory.img
|
||||||
|
dgn3500sum $(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory-prepad.img $(DGN3500_SKERNEL) DE
|
||||||
|
$(call prepare_generic_squashfs,$(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory-prepad.img)
|
||||||
|
dd if=$(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory-prepad.img of=$(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory.img conv=notrunc
|
||||||
|
dd if=$(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory-prepad.img of=$(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-sysupgrade.image bs=$(DGN3500_SKERNEL_DECIMAL) skip=1
|
||||||
|
rm -r $(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-factory-prepad.img
|
||||||
|
dgn3500sum $(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1)-sysupgrade.image $(DGN3500_SKERNEL) DE
|
||||||
|
endef
|
||||||
|
|
||||||
|
|
||||||
define Image/BuildTPLink/squashfs
|
define Image/BuildTPLink/squashfs
|
||||||
mktplinkfw2 -B $(3) -s -a 0x4 -j \
|
mktplinkfw2 -B $(3) -s -a 0x4 -j \
|
||||||
-k $(KDIR)/vmlinux-$(2).lzma -r $(KDIR)/root.$(1) \
|
-k $(KDIR)/vmlinux-$(2).lzma -r $(KDIR)/root.$(1) \
|
||||||
|
@ -316,10 +353,10 @@ Image/Build/Profile/GIGASX76X=$(call Image/Build/$(1),$(1),GIGASX76X)
|
||||||
|
|
||||||
# AR9
|
# AR9
|
||||||
Image/BuildKernel/Profile/DGN3500=$(call Image/BuildKernel/Template,DGN3500)
|
Image/BuildKernel/Profile/DGN3500=$(call Image/BuildKernel/Template,DGN3500)
|
||||||
Image/Build/Profile/DGN3500=$(call Image/Build/$(1),$(1),DGN3500)
|
Image/Build/Profile/DGN3500=$(call Image/BuildDGN3500/$(1),$(1),DGN3500)
|
||||||
|
|
||||||
Image/BuildKernel/Profile/DGN3500B=$(call Image/BuildKernel/Template,DGN3500)
|
Image/BuildKernel/Profile/DGN3500B=$(call Image/BuildKernel/Template,DGN3500B)
|
||||||
Image/Build/Profile/DGN3500B=$(call Image/Build/$(1),$(1),DGN3500)
|
Image/Build/Profile/DGN3500B=$(call Image/BuildDGN3500B/$(1),$(1),DGN3500B)
|
||||||
|
|
||||||
Image/BuildKernel/Profile/WBMRA=$(call Image/BuildKernel/Template,WBMR)
|
Image/BuildKernel/Profile/WBMRA=$(call Image/BuildKernel/Template,WBMR)
|
||||||
Image/Build/Profile/WBMRA=$(call Image/Build/$(1),$(1),WBMR)
|
Image/Build/Profile/WBMRA=$(call Image/Build/$(1),$(1),WBMR)
|
||||||
|
|
|
@ -68,6 +68,7 @@ define Host/Compile
|
||||||
$(call cc,mkdcs932, -Wall)
|
$(call cc,mkdcs932, -Wall)
|
||||||
$(call cc,mkheader_gemtek,-lz)
|
$(call cc,mkheader_gemtek,-lz)
|
||||||
$(call cc,mkrtn56uimg, -lz)
|
$(call cc,mkrtn56uimg, -lz)
|
||||||
|
$(call cc,dgn3500sum)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Host/Install
|
define Host/Install
|
||||||
|
|
167
tools/firmware-utils/src/dgn3500sum.c
Normal file
167
tools/firmware-utils/src/dgn3500sum.c
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
/* **************************************************************************
|
||||||
|
|
||||||
|
This program creates a modified 16bit checksum used for the Netgear
|
||||||
|
DGN3500 series routers. The difference between this and a standard
|
||||||
|
checksum is that every 0x100 bytes added 0x100 have to be subtracted
|
||||||
|
from the sum.
|
||||||
|
|
||||||
|
(C) 2013 Marco Antonio Mauro <marcus90 at gmail.com>
|
||||||
|
|
||||||
|
Based on previous unattributed work.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
************************************************************************* */
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
unsigned char PidDataWW[70] =
|
||||||
|
{
|
||||||
|
0x73, 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x59, 0x50, 0x35, 0x37, 0x32,
|
||||||
|
0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x37,
|
||||||
|
0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73,
|
||||||
|
0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D,
|
||||||
|
} ;
|
||||||
|
|
||||||
|
unsigned char PidDataDE[70] =
|
||||||
|
{
|
||||||
|
0x73, 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x59, 0x50, 0x35, 0x37, 0x32,
|
||||||
|
0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x37,
|
||||||
|
0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73,
|
||||||
|
0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D,
|
||||||
|
} ;
|
||||||
|
|
||||||
|
unsigned char PidDataNA[70] =
|
||||||
|
{
|
||||||
|
0x73, 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x59, 0x50, 0x35, 0x37, 0x32,
|
||||||
|
0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x37,
|
||||||
|
0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73,
|
||||||
|
0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D,
|
||||||
|
} ;
|
||||||
|
|
||||||
|
/* *******************************************************************
|
||||||
|
Reads the file into memory and returns pointer to the buffer. */
|
||||||
|
static char *readfile(char *filename, int *size)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
char *buffer;
|
||||||
|
struct stat info;
|
||||||
|
|
||||||
|
if (stat(filename,&info)!=0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if ((fp=fopen(filename,"r"))==NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
buffer=NULL;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if ((buffer=(char *)malloc(info.st_size+1))==NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (fread(buffer,1,info.st_size,fp)!=info.st_size)
|
||||||
|
{
|
||||||
|
free(buffer);
|
||||||
|
buffer=NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[info.st_size]='\0';
|
||||||
|
if(size) *size = info.st_size;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)fclose(fp);
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ******************************************************************* */
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
unsigned long start, i;
|
||||||
|
char *endptr, *buffer, *p;
|
||||||
|
int count; // size of file in bytes
|
||||||
|
unsigned short sum, sum1;
|
||||||
|
char sumbuf[9];
|
||||||
|
|
||||||
|
if(argc < 3) {
|
||||||
|
printf("ERROR: Argument missing!\n\nUsage %s filename starting offset in hex [PID code]\n\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FILE *fp = fopen(argv[1], "a");
|
||||||
|
if(!fp) {
|
||||||
|
printf("ERROR: File not writeable!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(argc = 4)
|
||||||
|
{
|
||||||
|
printf("%s: PID type: %s\n", argv[0], argv[3]);
|
||||||
|
if(strcmp(argv[3], "DE")==0)
|
||||||
|
fwrite(PidDataDE, sizeof(PidDataDE), sizeof(char), fp); /* write DE pid */
|
||||||
|
else if(strcmp(argv[3], "NA")==0)
|
||||||
|
fwrite(PidDataNA, sizeof(PidDataNA), sizeof(char), fp); /* write NA pid */
|
||||||
|
else /* if(strcmp(argv[3], "WW")) */
|
||||||
|
fwrite(PidDataWW, sizeof(PidDataWW), sizeof(char), fp); /* write WW pid */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fwrite(PidDataWW, sizeof(PidDataWW), sizeof(char), fp); /* write WW pid if unspecified */
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
/* Read the file to calculate the checksums */
|
||||||
|
buffer = readfile(argv[1], &count);
|
||||||
|
if(!buffer) {
|
||||||
|
printf("ERROR: File %s not found!\n", argv[1]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = buffer;
|
||||||
|
for(i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
sum += p[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
start = strtol(argv[2], &endptr, 16);
|
||||||
|
p = buffer+start;
|
||||||
|
sum1 = 0;
|
||||||
|
for(i = 0; i < count - start; i++)
|
||||||
|
{
|
||||||
|
sum1 += p[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(sumbuf,"%04X%04X",sum1,sum);
|
||||||
|
/* Append the 2 checksums to end of file */
|
||||||
|
fp = fopen(argv[1], "a");
|
||||||
|
if(!fp) {
|
||||||
|
printf("ERROR: File not writeable!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
fwrite(sumbuf, 8, sizeof(char), fp);
|
||||||
|
fclose(fp);
|
||||||
|
free(buffer);
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in a new issue