diff options
Diffstat (limited to 'target/wag54g/tools')
-rw-r--r-- | target/wag54g/tools/addpattern/Makefile | 4 | ||||
-rw-r--r-- | target/wag54g/tools/addpattern/addpattern.c | 255 | ||||
-rw-r--r-- | target/wag54g/tools/rules.mk | 9 | ||||
-rw-r--r-- | target/wag54g/tools/squashfs/Makefile | 27 | ||||
-rw-r--r-- | target/wag54g/tools/srec2bin/Makefile | 4 | ||||
-rw-r--r-- | target/wag54g/tools/srec2bin/srec2bin.c | 524 |
6 files changed, 823 insertions, 0 deletions
diff --git a/target/wag54g/tools/addpattern/Makefile b/target/wag54g/tools/addpattern/Makefile new file mode 100644 index 000000000..3ac1884fa --- /dev/null +++ b/target/wag54g/tools/addpattern/Makefile @@ -0,0 +1,4 @@ +include $(TOPDIR)/rules.mk + +all: + $(HOSTCC) ${HOSTCFLAGS} -o ${STAGING_TOOLS}/bin/addpattern addpattern.c diff --git a/target/wag54g/tools/addpattern/addpattern.c b/target/wag54g/tools/addpattern/addpattern.c new file mode 100644 index 000000000..6f2a036c0 --- /dev/null +++ b/target/wag54g/tools/addpattern/addpattern.c @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2004 Manuel Novoa III <mjn3@codepoet.org> + * + * 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 + */ + +/* July 29, 2004 + * + * This is a hacked replacement for the 'addpattern' utility used to + * create wrt54g .bin firmware files. It isn't pretty, but it does + * the job for me. + * + * Extensions: + * -v allows setting the version string on the command line. + * -{0|1} sets the (currently ignored) hw_ver flag in the header + * to 0 or 1 respectively. + */ + +/* January 12, 2005 + * + * Modified by rodent at rodent dot za dot net + * Support added for the new WRT54G v2.2 and WRT54GS v1.1 "flags" + * Without the flags set to 0x7, the above units will refuse to flash. + * + * Extensions: + * -{0|1|2} sets {0|1} sets hw_ver flag to 0/1. {2} sets hw_ver to 1 + * and adds the new hardware "flags" for the v2.2/v1.1 units +*/ + +/* January 1, 2007 + * + * Modified by juan.i.gonzalez at subdown dot net + * Support added for the AG241v2 and similar + * + * Extensions: + * -r #.# adds revision hardware flags. AG241v2 and similar. + * + * AG241V2 firmware sets the hw_ver to 0x44. + * + * Example: -r 2.0 + * + * Convert 2.0 to 20 to be an integer, and add 0x30 to skip special ASCII + * #define HW_Version ((HW_REV * 10) + 0x30) -> from cyutils.h +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#include <sys/stat.h> + +/**********************************************************************/ + +#define CODE_ID "U2ND" /* from code_pattern.h */ +#define CODE_PATTERN "W54S" /* from code_pattern.h */ +#define PBOT_PATTERN "PBOT" + +#define CYBERTAN_VERSION "v3.37.2" /* from cyutils.h */ + +/* WRT54G v2.2 and WRT54GS v1.1 "flags" (from 3.37.32 firmware cyutils.h) */ +#define SUPPORT_4712_CHIP 0x0001 +#define SUPPORT_INTEL_FLASH 0x0002 +#define SUPPORT_5325E_SWITCH 0x0004 + +struct code_header { /* from cyutils.h */ + char magic[4]; + char res1[4]; /* for extra magic */ + char fwdate[3]; + char fwvern[3]; + char id[4]; /* U2ND */ + char hw_ver; /* 0: for 4702, 1: for 4712 -- new in 2.04.3 */ + char unused; + unsigned char flags[2]; /* SUPPORT_ flags new for 3.37.2 (WRT54G v2.2 and WRT54GS v1.1) */ + unsigned char res2[10]; +} ; + +/**********************************************************************/ + +void usage(void) __attribute__ (( __noreturn__ )); + +void usage(void) +{ + fprintf(stderr, "Usage: addpattern [-i trxfile] [-o binfile] [-p pattern] [-g] [-b] [-v v#.#.#] [-r #.#] [-{0|1|2|4}] -h\n"); + exit(EXIT_FAILURE); +} + +int main(int argc, char **argv) +{ + char buf[1024]; /* keep this at 1k or adjust garbage calc below */ + struct code_header *hdr; + FILE *in = stdin; + FILE *out = stdout; + char *ifn = NULL; + char *ofn = NULL; + char *pattern = CODE_PATTERN; + char *pbotpat = PBOT_PATTERN; + char *version = CYBERTAN_VERSION; + int gflag = 0; + int pbotflag = 0; + int c; + int v0, v1, v2; + size_t off, n; + time_t t; + struct tm *ptm; + + fprintf(stderr, "mjn3's addpattern replacement - v0.81\n"); + + hdr = (struct code_header *) buf; + memset(hdr, 0, sizeof(struct code_header)); + + while ((c = getopt(argc, argv, "i:o:p:gbv:0124hr:")) != -1) { + switch (c) { + case 'i': + ifn = optarg; + break; + case 'o': + ofn = optarg; + break; + case 'p': + pattern = optarg; + break; + case 'g': + gflag = 1; + break; + case 'b': + pbotflag = 1; + break; + case 'v': /* extension to allow setting version */ + version = optarg; + break; + case '0': + hdr->hw_ver = 0; + break; + case '1': + hdr->hw_ver = 1; + break; + case '2': /* new 54G v2.2 and 54GS v1.1 flags */ + hdr->hw_ver = 1; + hdr->flags[0] |= SUPPORT_4712_CHIP; + hdr->flags[0] |= SUPPORT_INTEL_FLASH; + hdr->flags[0] |= SUPPORT_5325E_SWITCH; + break; + case '4': + /* V4 firmware sets the flags to 0x1f */ + hdr->hw_ver = 0; + hdr->flags[0] = 0x1f; + break; + case 'r': + hdr->hw_ver = (char)(atof(optarg)*10)+0x30; + break; + + case 'h': + default: + usage(); + } + } + + if (optind != argc || optind == 1) { + fprintf(stderr, "illegal arg \"%s\"\n", argv[optind]); + usage(); + } + + if (strlen(pattern) != 4) { + fprintf(stderr, "illegal pattern \"%s\": length != 4\n", pattern); + usage(); + } + + if (ifn && !(in = fopen(ifn, "r"))) { + fprintf(stderr, "can not open \"%s\" for reading\n", ifn); + usage(); + } + + if (ofn && !(out = fopen(ofn, "w"))) { + fprintf(stderr, "can not open \"%s\" for writing\n", ofn); + usage(); + } + + if (time(&t) == (time_t)(-1)) { + fprintf(stderr, "time call failed\n"); + return EXIT_FAILURE; + } + + ptm = localtime(&t); + + if (3 != sscanf(version, "v%d.%d.%d", &v0, &v1, &v2)) { + fprintf(stderr, "bad version string \"%s\"\n", version); + return EXIT_FAILURE; + } + + memcpy(&hdr->magic, pattern, 4); + if (pbotflag) + memcpy(&hdr->res1, pbotpat, 4); + hdr->fwdate[0] = ptm->tm_year % 100; + hdr->fwdate[1] = ptm->tm_mon + 1; + hdr->fwdate[2] = ptm->tm_mday; + hdr->fwvern[0] = v0; + hdr->fwvern[1] = v1; + hdr->fwvern[2] = v2; + memcpy(&hdr->id, CODE_ID, strlen(CODE_ID)); + + off = sizeof(struct code_header); + + fprintf(stderr, "writing firmware v%d.%d.%d on %d/%d/%d (y/m/d)\n", + v0, v1, v2, + hdr->fwdate[0], hdr->fwdate[1], hdr->fwdate[2]); + + + while ((n = fread(buf + off, 1, sizeof(buf)-off, in) + off) > 0) { + off = 0; + if (n < sizeof(buf)) { + if (ferror(in)) { + FREAD_ERROR: + fprintf(stderr, "fread error\n"); + return EXIT_FAILURE; + } + if (gflag) { + gflag = sizeof(buf) - n; + memset(buf + n, 0xff, gflag); + fprintf(stderr, "adding %d bytes of garbage\n", gflag); + n = sizeof(buf); + } + } + if (!fwrite(buf, n, 1, out)) { + FWRITE_ERROR: + fprintf(stderr, "fwrite error\n"); + return EXIT_FAILURE; + } + } + + if (ferror(in)) { + goto FREAD_ERROR; + } + + if (fflush(out)) { + goto FWRITE_ERROR; + } + + fclose(in); + fclose(out); + + return EXIT_SUCCESS; +} diff --git a/target/wag54g/tools/rules.mk b/target/wag54g/tools/rules.mk new file mode 100644 index 000000000..8d03c031a --- /dev/null +++ b/target/wag54g/tools/rules.mk @@ -0,0 +1,9 @@ +# $Id$ +#- +# This file is part of the OpenADK project. OpenADK is copyrighted +# material, please see the LICENCE file in the top-level directory. + +WRKDIR_BASE= ${TOOLS_BUILD_DIR} +WRKDIR= ${WRKDIR_BASE} + +include ${TOPDIR}/mk/buildhlp.mk diff --git a/target/wag54g/tools/squashfs/Makefile b/target/wag54g/tools/squashfs/Makefile new file mode 100644 index 000000000..0887afc22 --- /dev/null +++ b/target/wag54g/tools/squashfs/Makefile @@ -0,0 +1,27 @@ +# $Id$ +#- +# This file is part of the OpenADK project. OpenADK is copyrighted +# material, please see the LICENCE file in the top-level directory. + +include $(TOPDIR)/rules.mk + +PKG_NAME:= squashfs +PKG_VERSION:= 4.0 +PKG_RELEASE:= 1 +PKG_MD5SUM:= a3c23391da4ebab0ac4a75021ddabf96 +PKG_SITES:= ${MASTER_SITE_SOURCEFORGE:=squashfs/} +DISTFILES:= ${PKG_NAME}${PKG_VERSION}.tar.gz +WRKDIST= ${WRKDIR}/$(PKG_NAME)${PKG_VERSION} + +include ../rules.mk + +$(WRKBUILD)/.compiled: ${WRKDIST}/.prepared + $(MAKE) -C $(WRKBUILD)/squashfs-tools + touch $@ + +$(WRKBUILD)/.installed: + $(INSTALL_BIN) $(WRKBUILD)/squashfs-tools/mksquashfs \ + ${STAGING_TOOLS}/bin + touch $@ + +include $(TOPDIR)/mk/tools.mk diff --git a/target/wag54g/tools/srec2bin/Makefile b/target/wag54g/tools/srec2bin/Makefile new file mode 100644 index 000000000..dd6a285fd --- /dev/null +++ b/target/wag54g/tools/srec2bin/Makefile @@ -0,0 +1,4 @@ +include $(TOPDIR)/rules.mk + +all: + $(HOSTCC) ${HOSTCFLAGS} -o ${STAGING_TOOLS}/bin/srec2bin srec2bin.c diff --git a/target/wag54g/tools/srec2bin/srec2bin.c b/target/wag54g/tools/srec2bin/srec2bin.c new file mode 100644 index 000000000..1cffbaed9 --- /dev/null +++ b/target/wag54g/tools/srec2bin/srec2bin.c @@ -0,0 +1,524 @@ +#include <stdio.h> +#include <ctype.h> +#include <string.h> + +//Rev 0.1 Original +// 8 Jan 2001 MJH Added code to write data to Binary file +// note: outputfile is name.bin, where name is first part +// of input file. ie tmp.rec -> tmp.bin +// +// srec2bin <input SREC file> <Output Binary File> <If Present, Big Endian> +// +// TAG +// bit32u TAG_BIG = 0xDEADBE42; +// bit32u TAG_LITTLE = 0xFEEDFA42; +// +// File Structure +// +// TAG : 32 Bits +// [DATA RECORDS] +// +// Data Records Structure +// +// LENGTH : 32 Bits <- Length of DATA, excludes ADDRESS and CHECKSUM +// ADDRESS : 32 Bits +// DATA : 8 Bits * LENGTH +// CHECKSUM: 32 Bits <- 0 - (Sum of Length --> End of Data) +// +// Note : If Length == 0, Address will be Program Start +// +// +// +// +// + +#define MajRevNum 0 +#define MinRevNum 2 + + +#define EndianSwitch(x) ((x >> 24) | (x << 24) | ((x << 8) & (0x00FF0000)) | ((x >> 8) & (0x0000FF00)) ) + +typedef unsigned char bit8u; +typedef unsigned int bit32u; +typedef int bit32; + +#define FALSE 0 +#define TRUE (!FALSE) + + +bit32u CheckSum; +int RecStart; +int debug; +int verbose; + +FILE *OpenOutputFile( char *Name ); +FILE *fOut; +bit32u RecLength=0; + +bit32u AddressCurrent; + +bit32u gh(char *cp,int nibs); + +int BigEndian; + +int inputline; + +// char buf[16*1024]; + +char buffer[2048]; +char *cur_ptr; +int cur_line=0; +int cur_len=0; + +int s1s2s3_total=0; + +bit32u PBVal; +int PBValid; +bit32u PBAdr; + + +void dumpfTell(char *s, bit32u Value) +{ + int Length; + Length = (int) RecLength; + if (debug) + printf("[%s ] ftell()[0x%08lX] Length[0x%4X] Length[%4d] Value[0x%08x]\n", + s, ftell(fOut), Length, Length, Value); +} + +void DispHex(bit32u Hex) +{ +// printf("%X", Hex); +} + +void WaitDisplay(void) +{ + static int Count=0; + static int Index=0; + char iline[]={"-\\|/"}; + + Count++; + if ((Count % 32)==0) + { + if (verbose) + printf("%c%c",iline[Index++],8); + Index &= 3; + } +} + + +void binOut32 ( bit32u Data ) +{ +// On UNIX machine all 32bit writes need ENDIAN switched +// Data = EndianSwitch(Data); +// fwrite( &Data, sizeof(bit32u), 1, fOut); + + char sdat[4]; + int i; + + for(i=0;i<4;i++) + sdat[i]=(char)(Data>>(i*8)); + fwrite( sdat, 1, 4, fOut); + dumpfTell("Out32" , Data); +} + +// Only update RecLength on Byte Writes +// All 32 bit writes will be for Length etc + +void binOut8 ( bit8u Data ) +{ + int n; + dumpfTell("B4Data" , (bit32u) (Data & 0xFF) ); + n = fwrite( &Data, sizeof(bit8u), 1, fOut); + if (n != 1) + printf("Error in writing %X for Address 0x%8X\n", Data, AddressCurrent); + RecLength += 1; +} + +// Currently ONLY used for outputting Program Start + +void binRecStart(bit32u Address) +{ + RecLength = 0; + CheckSum = Address; + RecStart = TRUE; + + if (debug) + printf("[RecStart] CheckSum[0x%08X] Length[%4d] Address[0x%08X]\n", + CheckSum, RecLength, Address); + + + dumpfTell("RecLength", RecLength); + binOut32( RecLength ); + dumpfTell("Address", Address); + binOut32( Address ); +} + +void binRecEnd(void) +{ + long RecEnd; + + if (!RecStart) // if no record started, do not end it + { + return; + } + + RecStart = FALSE; + + + RecEnd = ftell(fOut); // Save Current position + + if (debug) + printf("[RecEnd ] CheckSum[0x%08X] Length[%4d] Length[0x%X] RecEnd[0x%08lX]\n", + CheckSum, RecLength, RecLength, RecEnd); + + fseek( fOut, -((long) RecLength), SEEK_CUR); // move back Start Of Data + + dumpfTell("Data ", -1); + + fseek( fOut, -4, SEEK_CUR); // move back Start Of Address + + dumpfTell("Address ", -1); + + fseek( fOut, -4, SEEK_CUR); // move back Start Of Length + + dumpfTell("Length ", -1); + + binOut32( RecLength ); + + fseek( fOut, RecEnd, SEEK_SET); // move to end of Record + + CheckSum += RecLength; + + CheckSum = ~CheckSum + 1; // Two's complement + + binOut32( CheckSum ); + + if (verbose) + printf("[Created Record of %d Bytes with CheckSum [0x%8X]\n", RecLength, CheckSum); +} + +void binRecOutProgramStart(bit32u Address) +{ + if (Address != (AddressCurrent+1)) + { + binRecEnd(); + binRecStart(Address); + } + AddressCurrent = Address; +} +void binRecOutByte(bit32u Address, bit8u Data) +{ + // If Address is one after Current Address, output Byte + // If not, close out last record, update Length, write checksum + // Then Start New Record, updating Current Address + + if (Address != (AddressCurrent+1)) + { + binRecEnd(); + binRecStart(Address); + } + AddressCurrent = Address; + CheckSum += Data; + binOut8( Data ); +} + +//============================================================================= +// SUPPORT FUNCTIONS +//============================================================================= +int readline(FILE *fil,char *buf,int len) +{ + int rlen; + + rlen=0; + if (len==0) return(0); + while(1) + { + if (cur_len==0) + { + cur_len=fread(buffer, 1, sizeof(buffer), fil); + if (cur_len==0) + { + if (rlen) + { + *buf=0; + return(rlen); + } + return(-1); + } + cur_ptr=buffer; + } + if (cur_len) + { + if (*cur_ptr=='\n') + { + *buf=0; + cur_ptr++; + cur_len--; + return(rlen); + } + else + { + if ((len>1)&&(*cur_ptr!='\r')) + { + *buf++=*cur_ptr++; + len--; + } + else + cur_ptr++; + + rlen++; + cur_len--; + } + } + else + { + *buf=0; + cur_ptr++; + cur_len--; + return(rlen); + } + } +} + + +int SRLerrorout(char *c1,char *c2) +{ + printf("\nERROR: %s - '%s'.",c1,c2); + return(FALSE); +} + + +int checksum(char *cp,int count) +{ + char *scp; + int cksum; + int dum; + + scp=cp; + while(*scp) + { + if (!isxdigit(*scp++)) + return(SRLerrorout("Invalid hex digits",cp)); + } + scp=cp; + + cksum=count; + + while(count) + { + cksum += gh(scp,2); + if (count == 2) + dum = ~cksum; + scp += 2; + count--; + } + cksum&=0x0ff; + // printf("\nCk:%02x",cksum); + return(cksum==0x0ff); +} + +bit32u gh(char *cp,int nibs) +{ + int i; + bit32u j; + + j=0; + + for(i=0;i<nibs;i++) + { + j<<=4; + if ((*cp>='a')&&(*cp<='z')) *cp &= 0x5f; + if ((*cp>='0')&&(*cp<='9')) + j += (*cp-0x30); + else + if ((*cp>='A')&&(*cp<='F')) + j += (*cp-0x37); + else + SRLerrorout("Bad Hex char", cp); + cp++; + } + return(j); +} + + +//============================================================================= +// PROCESS SREC LINE +//============================================================================= + +int srecLine(char *pSrecLine) +{ + char *scp,ch; + int itmp,count,dat; + bit32u adr; + static bit32u RecordCounter=0; + + cur_line++; + scp=pSrecLine; + + if (*pSrecLine!='S') + return(SRLerrorout("Not an Srecord file",scp)); + pSrecLine++; + if (strlen(pSrecLine)<4) + return(SRLerrorout("Srecord too short",scp)); + + ch=*pSrecLine++; + + count=gh(pSrecLine,2); + + pSrecLine += 2; + + // if(debug) + // printf("count %d, strlen(pSrecLine) = %d, pSrecLine =[%s]\n", count, strlen(pSrecLine), pSrecLine); + RecordCounter++; + DispHex(RecordCounter); + + if ((count*2) != strlen(pSrecLine)) return(SRLerrorout("Count field larger than record",scp)); + + if (!checksum(pSrecLine, count)) return(SRLerrorout("Bad Checksum",scp)); + + switch(ch) + { + case '0': if (count<3) return(SRLerrorout("Invalid Srecord count field",scp)); + itmp=gh(pSrecLine,4); pSrecLine+=4; count-=2; + if (itmp) return(SRLerrorout("Srecord 1 address not zero",scp)); + break; + case '1': if (count<3) return(SRLerrorout("Invalid Srecord count field",scp)); + return(SRLerrorout("Srecord Not valid for MIPS",scp)); + break; + case '2': if (count<4) return(SRLerrorout("Invalid Srecord count field",scp)); + return(SRLerrorout("Srecord Not valid for MIPS",scp)); + break; + case '3': if (count<5) return(SRLerrorout("Invalid Srecord count field",scp)); + adr=gh(pSrecLine,8); pSrecLine+=8; count-=4; + count--; + while(count) + { + dat=gh(pSrecLine,2); pSrecLine+=2; count--; + binRecOutByte(adr, (char) (dat & 0xFF)); + adr++; + } + s1s2s3_total++; + break; + case '4': return(SRLerrorout("Invalid Srecord type",scp)); + break; + case '5': if (count<3) return(SRLerrorout("Invalid Srecord count field",scp)); + itmp=gh(pSrecLine,4); pSrecLine+=4; count-=2; + if (itmp|=s1s2s3_total) return(SRLerrorout("Incorrect number of S3 Record processed",scp)); + break; + case '6': return(SRLerrorout("Invalid Srecord type",scp)); + break; + case '7': // PROGRAM START + if (count<5) return(SRLerrorout("Invalid Srecord count field",scp)); + adr=gh(pSrecLine,8); pSrecLine+=8; count-=4; + if (count!=1) return(SRLerrorout("Invalid Srecord count field",scp)); + binRecOutProgramStart(adr); + break; + case '8': if (count<4) return(SRLerrorout("Invalid Srecord count field",scp)); + return(SRLerrorout("Srecord Not valid for MIPS",scp)); + break; + case '9': if (count<3) return(SRLerrorout("Invalid Srecord count field",scp)); + return(SRLerrorout("Srecord Not valid for MIPS",scp)); + break; + default: + break; + } + return(TRUE); +} + + +//============================================================================= +// MAIN LOGIC, READS IN LINE AND OUTPUTS BINARY +//============================================================================= + +int srec2bin(int argc,char *argv[],int verbose) +{ + int i,rlen,sts; + FILE *fp; + char ac; + char buff[256]; + bit32u TAG_BIG = 0xDEADBE42; + bit32u TAG_LITTLE = 0xFEEDFA42; + + bit32u Tag; + + + if(argc < 3) + { + printf("\nError: <srec2bin <srec input file> <bin output file>\n\n"); + return(0); + } + + if (argc > 3) BigEndian=TRUE; else BigEndian=FALSE; + + if (BigEndian) + Tag = TAG_BIG; + else + Tag = TAG_LITTLE; + + if (verbose) + printf("\nEndian: %s, Tag is 0x%8X\n",(BigEndian)?"BIG":"LITTLE", Tag); + + fp = fopen(argv[1],"rt"); + + if (fp==NULL) + { + printf("\nError: Opening input file, %s.", argv[1]); + return(0); + } + + fOut = fopen( argv[2], "wb"); + + if (fOut==NULL) + { + printf("\nError: Opening Output file, %s.", argv[2]); + if(fp) fclose(fp); + return(0); + } + + RecStart = FALSE; + + AddressCurrent = 0xFFFFFFFFL; + + // Setup Tag + + dumpfTell("Tag", Tag); + + binOut32(Tag); + + + inputline=0; + sts=TRUE; + + rlen = readline(fp,buff,sizeof buff); + + while( (sts) && (rlen != -1)) + { + if (strlen(buff)) + { + sts &= srecLine(buff); + WaitDisplay(); + } + rlen = readline(fp,buff,sizeof buff); + } + + + // printf("PC: 0x%08X, Length 0x%08X, Tag 0x%08X\n", ProgramStart, RecLength, TAG_LITTLE); + + binRecEnd(); + + if(fp) fclose(fp); + if(fOut) fclose(fOut); + + return(1); +} + +main(int argc, char *argv[]) +{ + debug = TRUE; + debug = FALSE; + verbose = FALSE; + srec2bin(argc,argv,verbose); + return 0; +} + |