X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fopenwrt.git;a=blobdiff_plain;f=tools%2Ffirmware-utils%2Fsrc%2Faddpattern.c;h=9bc48653356291c1568e020a6f5bcdc35822fb09;hp=6f2a036c0b37238d1260360758e30645ea2daff0;hb=c47a1a3527d988b637c1daee573cbe0170ef73c6;hpb=001f82bf2cc51d3a3cba212b2f38dd9fa961a5c7 diff --git a/tools/firmware-utils/src/addpattern.c b/tools/firmware-utils/src/addpattern.c index 6f2a036c0b..9bc4865335 100644 --- a/tools/firmware-utils/src/addpattern.c +++ b/tools/firmware-utils/src/addpattern.c @@ -29,11 +29,11 @@ */ /* 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 @@ -58,6 +58,7 @@ #include #include #include +#include #include #include #include @@ -74,29 +75,98 @@ #define SUPPORT_4712_CHIP 0x0001 #define SUPPORT_INTEL_FLASH 0x0002 #define SUPPORT_5325E_SWITCH 0x0004 +/* (from 3.00.24 firmware cyutils.h) */ +#define SUPPORT_4704_CHIP 0x0008 +#define SUPPORT_5352E_CHIP 0x0010 +/* (from WD My Net Wi-Fi Range Extender's cyutils.s) */ +#define SUPPORT_4703_CHIP 0x0020 struct code_header { /* from cyutils.h */ - char magic[4]; - char res1[4]; /* for extra magic */ + char magic[8]; 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]; + + unsigned char sn; // Serial Number + unsigned char flags[2]; /* SUPPORT_ flags new for 3.37.2 (WRT54G v2.2 and WRT54GS v1.1) */ + unsigned char stable[2]; // The image is stable (for dual image) + unsigned char try1[2]; // Try to boot image first time (for dual image) + unsigned char try2[2]; // Try to boot image second time (for dual image) + unsigned char try3[2]; // Try to boot image third time (for dual_image) + unsigned char res3[2]; } ; +struct board_info { + char *id; + char *pattern; + char hw_ver; + char sn; + char flags[2]; +}; + +struct board_info boards[] = { + { + .id = "E2100L", + .pattern = "NL1X", + .hw_ver = 0x00, + .sn = 0x0f, + .flags = {0x3f, 0x00}, + }, + { + .id = "WRT160NL", + .pattern = "NL16", + .hw_ver = 0x00, + .sn = 0x0f, + .flags = {0x3f, 0x00}, + }, + { + .id = "mynet-rext", + .pattern = "WDHNSTFH", + .hw_ver = 0x00, + .sn = 0x00, + .flags = {0x3f, 0x00}, + }, { + /* Terminating entry */ + .id = NULL, + } +}; + /**********************************************************************/ 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"); + fprintf(stderr, "Usage: addpattern [-i trxfile] [-o binfile] [-B board_id] [-p pattern] [-s serial] [-g] [-b] [-v v#.#.#] [-r #.#] [-{0|1|2|4|5}] -h\n"); exit(EXIT_FAILURE); } +static time_t source_date_epoch = -1; +static void set_source_date_epoch() { + char *env = getenv("SOURCE_DATE_EPOCH"); + char *endptr = env; + errno = 0; + if (env && *env) { + source_date_epoch = strtoull(env, &endptr, 10); + if (errno || (endptr && *endptr != '\0')) { + fprintf(stderr, "Invalid SOURCE_DATE_EPOCH"); + exit(1); + } + } +} + +struct board_info *find_board(char *id) +{ + struct board_info *board; + + for (board = boards; board->id != NULL; board++) + if (strcasecmp(id, board->id) == 0) + return board; + + return NULL; +} + int main(int argc, char **argv) { char buf[1024]; /* keep this at 1k or adjust garbage calc below */ @@ -108,6 +178,8 @@ int main(int argc, char **argv) char *pattern = CODE_PATTERN; char *pbotpat = PBOT_PATTERN; char *version = CYBERTAN_VERSION; + char *board_id = NULL; + struct board_info *board = NULL; int gflag = 0; int pbotflag = 0; int c; @@ -121,7 +193,7 @@ int main(int argc, char **argv) hdr = (struct code_header *) buf; memset(hdr, 0, sizeof(struct code_header)); - while ((c = getopt(argc, argv, "i:o:p:gbv:0124hr:")) != -1) { + while ((c = getopt(argc, argv, "i:o:p:s:gbv:01245hr:B:")) != -1) { switch (c) { case 'i': ifn = optarg; @@ -132,6 +204,9 @@ int main(int argc, char **argv) case 'p': pattern = optarg; break; + case 's': + hdr->sn = (unsigned char) atoi (optarg); + break; case 'g': gflag = 1; break; @@ -158,9 +233,21 @@ int main(int argc, char **argv) hdr->hw_ver = 0; hdr->flags[0] = 0x1f; break; + case '5': + /* V5 is appended to trxV2 image */ + hdr->stable[0] = 0x73; // force image to be stable + hdr->stable[1] = 0x00; + hdr->try1[0] = 0x74; // force try1 to be set + hdr->try1[1] = 0x00; + hdr->try2[0] = hdr->try2[1] = 0xFF; + hdr->try3[0] = hdr->try3[1] = 0xFF; + break; case 'r': hdr->hw_ver = (char)(atof(optarg)*10)+0x30; break; + case 'B': + board_id = optarg; + break; case 'h': default: @@ -173,8 +260,21 @@ int main(int argc, char **argv) usage(); } - if (strlen(pattern) != 4) { - fprintf(stderr, "illegal pattern \"%s\": length != 4\n", pattern); + if (board_id) { + board = find_board(board_id); + if (board == NULL) { + fprintf(stderr, "unknown board \"%s\"\n", board_id); + usage(); + } + pattern = board->pattern; + hdr->hw_ver = board->hw_ver; + hdr->sn = board->sn; + hdr->flags[0] = board->flags[0]; + hdr->flags[1] = board->flags[1]; + } + + if (strlen(pattern) > 8) { + fprintf(stderr, "illegal pattern \"%s\"\n", pattern); usage(); } @@ -188,7 +288,10 @@ int main(int argc, char **argv) usage(); } - if (time(&t) == (time_t)(-1)) { + set_source_date_epoch(); + if (source_date_epoch != -1) { + t = source_date_epoch; + } else if ((time(&t) == (time_t)(-1))) { fprintf(stderr, "time call failed\n"); return EXIT_FAILURE; } @@ -200,16 +303,16 @@ int main(int argc, char **argv) return EXIT_FAILURE; } - memcpy(&hdr->magic, pattern, 4); + memcpy(hdr->magic, pattern, strlen(pattern)); if (pbotflag) - memcpy(&hdr->res1, pbotpat, 4); + memcpy(&hdr->magic[4], 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)); + memcpy(hdr->id, CODE_ID, strlen(CODE_ID)); off = sizeof(struct code_header); @@ -239,7 +342,7 @@ int main(int argc, char **argv) return EXIT_FAILURE; } } - + if (ferror(in)) { goto FREAD_ERROR; }