[orion] update wrt350nv2-builder to v2.4 and use new functionality for target orion_g...
[openwrt.git] / tools / wrt350nv2-builder / src / wrt350nv2-builder.c
index 6800118..3ebb40e 100644 (file)
@@ -1,8 +1,8 @@
 /*
 
-       WRT350Nv2-Builder 2.1 (previously called buildimg)
+       WRT350Nv2-Builder 2.4 (previously called buildimg)
        Copyright (C) 2008-2009 Dirk Teurlings <info@upexia.nl>
-       Copyright (C) 2009-2010 Matthias Buecher (http://www.maddes.net/)
+       Copyright (C) 2009-2011 Matthias Buecher (http://www.maddes.net/)
 
        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
                :kernel 0x001A0000      /path/to/uImage
                :rootfs 0       /path/to/root.squashfs
                :u-boot 0       /path/to/u-boot.bin
+               #version        0x2020
+
+       Additionally since v2.4 an already complete image can be used:
+               :image          0       /path/to/openwrt-wrt350nv2-[squashfs|jffs2-64k].img
 
        args:
                1       wrt350nv2.par           parameter file describing the image layout
        To extract everything from a Linksys style firmware image see
        https://forum.openwrt.org/viewtopic.php?pid=92928#p92928
 
-*/
+       Changelog:
+       v2.4 - added ":image" definition for parameter file, this allows
+              to use a complete sysupgrade image without any kernel size check
+       v2.3 - allow jffs by adding its magic number (0x8519)
+              added parameter option -i to ignore unknown magic numbers
+       v2.2 - fixed checksum byte calculation for other versions than 0x2019
+              fixed rare problem with padsize
+              updated info to stock firmware 2.00.20
+              fixed typos
+       v2.1 - used "wrt350n.bin" for the created image (closer to stock)
+               added option to create the image in two separate steps (-b / -z)
+       v2.0 - complete re-write
 
-// ToDo:
-// * Has NODE to be added to bin file *after* creating checksum byte?
+*/
 
 // includes
 #define _GNU_SOURCE    // for GNU's basename()
 
 // custom includes
 #include "md5.h"       // MD5 routines
-#include "upgrade.h"   // Linksys definitions from firmware 2.0.19
+#include "upgrade.h"   // Linksys definitions from firmware 2.0.19 (unchanged up to 2.0.20)
 
 
 // version info
-#define VERSION "2.1"
+#define VERSION "2.4"
 char program_info[] = "WRT350Nv2-Builder v%s by Dirk Teurlings <info@upexia.nl> and Matthias Buecher (http://www.maddes.net/)\n";
 
 // verbosity
@@ -103,16 +117,19 @@ typedef struct {
 
 mtd_info mtd_kernel = { "kernel", 0, 0, NULL, 0L, { 0, 0 } };
 mtd_info mtd_rootfs = { "rootfs", 0, 0, NULL, 0L, { 0, 0 } };
+mtd_info mtd_image = { "image", 0, 0, NULL, 0L, { 0, 0 } };
 mtd_info mtd_uboot = { "u-boot", 0, 0, NULL, 0L, { 0, 0 } };
 
 #define ROOTFS_END_OFFSET      0x00760000
 #define ROOTFS_MIN_OFFSET      0x00640000      // should be filled up to here, to make sure that the zip file is big enough to pass the size check of the stock firmware
-                                               // 2.0.17: filled up to 0x00640000, 2.0.19: filled up to 0x0670000
+                                               // 2.0.17: filled up to 0x00640000
+                                               // 2.0.19: filled up to 0x00670000
+                                               // 2.0.20: filled up to 0x00670000
 
 // rootfs statics via: hexdump -v -e '1/1 "0x%02X, "' -s 0x0075FFE0 -n 16 "wrt350n.bin" ; echo -en "\n"
 unsigned char product_id[] = { 0x00, 0x03 };   // seems to be a fixed value
 unsigned char protocol_id[] = { 0x00, 0x00 };  // seems to be a fixed value
-unsigned char fw_version[] = { 0x20, 0x19 };
+unsigned char fw_version[] = { 0x20, 0x20 };
 unsigned char rootfs_unknown[] = { 0x90, 0xF7 };       // seems to be a fixed value
 unsigned char sign[] = { 0x65, 0x52, 0x63, 0x4F, 0x6D, 0x4D, 0x00, 0x00 };     // eRcOmM
 
@@ -130,7 +147,7 @@ unsigned char pid[] = {     0x73, 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, 0x00, 0x01, 0x
                                0x00, 0x00, 0x00, 0x04,
                                0x73, 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D };     // sErCoMm
 
-// img statics via: hexdump -v -e '1/1 "0x%02X, "' -s 0 -n 512 "WRT350N-EU-ETSI-2.00.19.img" ; echo -en "\n"
+// img statics via: hexdump -v -e '1/1 "0x%02X, "' -s 0 -n 512 "WRT350N-EU-ETSI-2.00.19.img" ; echo -en "\n" (unchanged up to 2.0.20)
 unsigned char img_hdr[] = {    0x00, 0x01, 0x00, 0x00, 0x59, 0x42, 0x50, 0x00, 0x01, 0x10, 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, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
@@ -270,6 +287,8 @@ int parse_par_file(FILE *f_par) {
                                                mtd = &mtd_rootfs;
                                        } else if (!strcmp(string1, mtd_uboot.name)) {
                                                mtd = &mtd_uboot;
+                                       } else if (!strcmp(string1, mtd_image.name)) {
+                                               mtd = &mtd_image;
                                        }
 
                                        if (!mtd) {
@@ -320,7 +339,7 @@ int parse_par_file(FILE *f_par) {
                        case '#':       // integer values
                                count = sscanf(line, "#%255s %i", string1, &value);
                                if (count != 2) {
-                                       printf("line %i does not meet defined format (:<variable name> <integer>\n", lineno);
+                                       printf("line %i does not meet defined format (#<variable name> <integer>\n", lineno);
                                } else {
                                        if (!strcmp(string1, "version")) {
                                                // changing version
@@ -393,20 +412,24 @@ int create_bin_file(char *bin_filename) {
 
        // add files
        if (!exitcode) {
-               for (i = 1; i <= 3; i++) {
+               for (i = 1; i <= 4; i++) {
                        addsize = 0;
                        padsize = 0;
 
                        switch (i) {
                                case 1:
-                                       mtd = &mtd_kernel;
+                                       mtd = &mtd_image;
+                                       padsize = ROOTFS_MIN_OFFSET - mtd->filesize;
                                        break;
                                case 2:
+                                       mtd = &mtd_kernel;
+                                       break;
+                               case 3:
                                        mtd = &mtd_rootfs;
                                        addsize = mtd->filesize;
                                        padsize = ROOTFS_MIN_OFFSET - mtd_kernel.size - mtd->filesize;
                                        break;
-                               case 3:
+                               case 4:
                                        mtd = &mtd_uboot;
                                        addsize = mtd->filesize;
                                        break;
@@ -454,10 +477,12 @@ int create_bin_file(char *bin_filename) {
 
                        // padding
                        if (padsize > 0) {
-                               printf("mtd %s input file %s is too small (0x%08lX), adding 0x%08X random bytes\n", mtd->name, mtd->filename, mtd->filesize, padsize);
-
                                addsize = padsize & 0x0000FFFF; // start on next 64KB border
                                padsize -= addsize;
+                       }
+                       if (padsize > 0) {
+                               printf("mtd %s input file %s is too small (0x%08lX), adding 0x%08X random bytes\n", mtd->name, mtd->filename, mtd->filesize, padsize);
+
                                addsize += KERNEL_CODE_OFFSET + mtd->offset + mtd->filesize;    // get offset
                                lprintf(DEBUG, " padding offset 0x%08X length 0x%08X\n", addsize, padsize);
 
@@ -491,10 +516,12 @@ int create_bin_file(char *bin_filename) {
                memcpy(&buffer[KERNEL_CODE_OFFSET + FW_VERSION_OFFSET + 2], rootfs_unknown, 2);
                memcpy(&buffer[KERNEL_CODE_OFFSET + SIGN_OFFSET], sign, 8);     // eRcOmM
 
-               lprintf(DEBUG, "adding u-boot special data 1/2\n");     // ToDo: or after creating the checksum byte?
-//             memcpy(&buffer[KERNEL_CODE_OFFSET + SN_OFF], sn, 12);   // ToDo: find out what's this for?
-//             memcpy(&buffer[KERNEL_CODE_OFFSET + PIN_OFF], pin, 8);  // ToDo: find out what's this for?
-//             memcpy(&buffer[KERNEL_CODE_OFFSET + NODE_BASE_OFF], node, 25);  // ToDo: find out what's this for?
+               lprintf(DEBUG, "adding u-boot special data\n");
+//             memcpy(&buffer[KERNEL_CODE_OFFSET + SN_OFF], sn, 12);   // ToDo: currently zero, find out what's this for?
+//             memcpy(&buffer[KERNEL_CODE_OFFSET + PIN_OFF], pin, 8);  // ToDo: currently zero, find out what's this for?
+//             memcpy(&buffer[KERNEL_CODE_OFFSET + NODE_BASE_OFF], node, 25);  // ToDo: currently zero, find out what's this for?
+               memcpy(&buffer[KERNEL_CODE_OFFSET + BOOT_ADDR_BASE_OFF + PID_OFFSET], pid, 70); // sErCoMm
+               memcpy(&buffer[KERNEL_CODE_OFFSET + BOOT_ADDR_BASE_OFF + PID_OFFSET + 57], fw_version, 2);
 
                lprintf(DEBUG, "adding checksum byte\n");
                csum = 0;
@@ -503,12 +530,8 @@ int create_bin_file(char *bin_filename) {
                }
                lprintf(DEBUG_LVL2, " checksum 0x%016lX (%li)\n", csum, csum);
 
-               buffer[KERNEL_CODE_OFFSET + NODE_BASE_OFF + 25] = ~(csum+108)+1;
+               buffer[KERNEL_CODE_OFFSET + NODE_BASE_OFF + 25] = ~csum + 1;
                lprintf(DEBUG, " byte 0x%02X\n", buffer[KERNEL_CODE_OFFSET + NODE_BASE_OFF + 25]);
-
-               lprintf(DEBUG, "adding u-boot special data 2/2\n");
-               memcpy(&buffer[KERNEL_CODE_OFFSET + BOOT_ADDR_BASE_OFF + PID_OFFSET], pid, 70); // sErCoMm
-               memcpy(&buffer[KERNEL_CODE_OFFSET + BOOT_ADDR_BASE_OFF + PID_OFFSET + 57], fw_version, 2);
        }
 
        // write bin file
@@ -699,6 +722,7 @@ int main(int argc, char *argv[]) {
        int help;
        int onlybin;
        int havezip;
+       int ignoremagic;
        char option;
        char *par_filename = NULL;
        char *img_filename = NULL;
@@ -711,10 +735,10 @@ int main(int argc, char *argv[]) {
 
        int i;
        mtd_info *mtd;
-       int mandatory;
        int noupdate;
        int sizecheck;
-       unsigned char magic[2];
+       int magiccheck;
+       int magicerror;
 
 
 // display program header
@@ -726,7 +750,8 @@ int main(int argc, char *argv[]) {
        help = 0;
        onlybin = 0;
        havezip = 0;
-       while ((option = getopt(argc, argv, ":hbzf:v")) != -1) {
+       ignoremagic = 0;
+       while ((option = getopt(argc, argv, "hbzif:v")) != -1) {
                switch(option) {
                        case 'h':
                                help = 1;
@@ -737,6 +762,9 @@ int main(int argc, char *argv[]) {
                        case 'z':
                                havezip = 1;
                                break;
+                       case 'i':
+                               ignoremagic = 1;
+                               break;
                        case 'f':
                                sizecheck = sscanf(optarg, "%i", &i);
                                if (sizecheck != 1) {
@@ -841,13 +869,14 @@ int main(int argc, char *argv[]) {
                        printf("This program creates Linksys style images for the WRT350Nv2 router.\n");
                }
                printf("  Usage:\n\
-  %s [-h] [-b] [-z] [-f <version>] [-v] <parameter or zip file> [<image file>]\n\n\
+  %s [-h] [-b] [-z] [-i] [-f <version>] [-v] <parameter or zip file> [<image file>]\n\n\
   Options:\n\
   -h            -  Show this help\n\
   -b            -  Create only bin file, no img or zip file is created\n\
   -z            -  Have zip file, the img file will be directly created from it\n\
+  -i            -  Ignore unknown magic numbers\n\
   -f <version>  -  Wanted firmware version to use with -z\n\
-                   Default firmware version is 0x2019 = 2.00.19.\n\
+                   Default firmware version is 0x2020 = 2.00.20.\n\
                    Note: version from parameter file will supersede this\n\
   -v            -  Increase debug verbosity level\n\n\
   Example:\n\
@@ -916,31 +945,30 @@ int main(int argc, char *argv[]) {
        if ((!exitcode) && (par_filename)) {
                lprintf(DEBUG, "checking mtd data...\n");
 
-               for (i = 1; i <= 3; i++) {
-                       mandatory = 0;
+               for (i = 1; i <= 4; i++) {
                        noupdate = 0;
                        sizecheck = 0;
-                       magic[0] = 0;
-                       magic[1] = 0;
+                       magiccheck = 0;
 
                        switch (i) {
                                case 1:
+                                       mtd = &mtd_image;
+                                       sizecheck = ROOTFS_END_OFFSET;
+                                       magiccheck = 1;
+                                       break;
+                               case 2:
                                        mtd = &mtd_kernel;
-                                       mandatory = 1;
                                        sizecheck = mtd_kernel.size - 16;
-                                       magic[0] = 0x27;
-                                       magic[1] = 0x05;
+                                       magiccheck = 1;
                                        break;
-                               case 2:
+                               case 3:
                                        mtd = &mtd_rootfs;
                                        mtd->offset = mtd_kernel.size;
                                        mtd->size = ROOTFS_END_OFFSET - mtd_kernel.size;
-                                       mandatory = 1;
                                        sizecheck = PRODUCT_ID_OFFSET - mtd_kernel.size;
-                                       magic[0] = 0x68;
-                                       magic[1] = 0x73;
+                                       magiccheck = 1;
                                        break;
-                               case 3:
+                               case 4:
                                        mtd = &mtd_uboot;
                                        mtd->offset = BOOT_ADDR_BASE_OFF;
                                        noupdate = 1;
@@ -959,12 +987,8 @@ int main(int argc, char *argv[]) {
                        lprintf(DEBUG_LVL2, " checking mtd %s\n", mtd->name);
 
                        // general checks
-                       if ((mandatory) && (!mtd->filename)) {
-                               exitcode = 1;
-                               printf("mtd %s not specified correctly or at all in parameter file\n", mtd->name);
-                       }
 
-                       // end checks if no file data present
+                       // no further checks if no file data present
                        if (!mtd->filename) {
                                continue;
                        }
@@ -975,16 +999,50 @@ int main(int argc, char *argv[]) {
                        }
 
                        // general magic number check
-                       if (magic[0]) {
-                               if ((mtd->magic[0] != magic[0]) || (mtd->magic[1] != magic[1])) {
-                                       exitcode = 1;
-                                       printf("mtd %s input file %s has wrong magic number (0x%02X%02X)\n", mtd->name, mtd->filename, mtd->magic[0], mtd->magic[1]);
+                       magicerror = 0;
+                       if (magiccheck) {
+                               switch (i) {
+                                       case 1: // image
+                                       case 2: // kernel
+                                               if (!( 
+                                                      ((mtd->magic[0] == 0x27) && (mtd->magic[1] == 0x05))     // uImage
+                                               )) {
+                                                       magicerror = 1;
+                                               }
+                                               break;
+                                       case 3: // rootfs
+                                               if (!( 
+                                                      ((mtd->magic[0] == 0x68) && (mtd->magic[1] == 0x73))     // squashfs
+                                                   || ((mtd->magic[0] == 0x85) && (mtd->magic[1] == 0x19))     // jffs
+                                               )) {
+                                                       magicerror = 1;
+                                               }
+                                               break;
+                                       default:
+                                               magicerror = 1;
+                                               break;
+                               }
+                               if (magicerror) {
+                                       printf("mtd %s input file %s has unknown magic number (0x%02X%02X)", mtd->name, mtd->filename, mtd->magic[0], mtd->magic[1]);
+                                       if (ignoremagic) {
+                                               printf("...ignoring");
+                                       } else {
+                                               exitcode = 1;
+                                       }
+                                       printf("\n");
                                }
                        }
 
                        // mtd specific size check
+                       if (mtd == &mtd_image) {
+                               if (mtd->filesize < 0x00200000) {
+                                       exitcode = 1;
+                                       printf("mtd %s input file %s too unrealistic small (0x%08lX)\n", mtd->name, mtd->filename, mtd->filesize);
+                               }
+                       }
+
                        if (mtd == &mtd_kernel) {
-                               if (mtd->filesize < 0x00050000) {
+                               if (mtd->filesize < 0x00080000) {
                                        exitcode = 1;
                                        printf("mtd %s input file %s too unrealistic small (0x%08lX)\n", mtd->name, mtd->filename, mtd->filesize);
                                }
@@ -1003,6 +1061,25 @@ int main(int argc, char *argv[]) {
                                }
                        }
                }
+
+               // Check for mandatory parts
+               if ((!mtd_image.filename) && (!mtd_kernel.filename || !mtd_rootfs.filename)) {
+                       exitcode = 1;
+                       if (mtd_kernel.filename && !mtd_rootfs.filename) {
+                               printf("Kernel without rootfs, either incorrectly specified or not at all in parameter file\n");
+                       } else if (!mtd_kernel.filename && mtd_rootfs.filename) {
+                               printf("Rootfs without kernel, either incorrectly specified or not at all in parameter file\n");
+                       } else {
+                               printf("Neither an image nor kernel with rootfs was/were correctly specified or at all in parameter file\n");
+                       }
+               }
+
+               // Check for duplicate parts
+               if ((mtd_image.filename) && (mtd_kernel.filename || mtd_rootfs.filename)) {
+                       exitcode = 1;
+                       printf("Image and kernel/rootfs specified in parameter file\n");
+               }
+
                lprintf(DEBUG, "...done checking mtd data\n");
        }
 
This page took 0.038806 seconds and 4 git commands to generate.