[tools] firmware-utils: ZyXEL firmware tool improvements
[openwrt.git] / tools / firmware-utils / src / mkzynfw.c
index e67ffa5..6beb007 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *  $Id$
  *
- *  Copyright (C) 2007 OpenWrt.org
- *  Copyright (C) 2007 Gabor Juhos <juhosg at openwrt.org>
+ *  Copyright (C) 2007-2008 OpenWrt.org
+ *  Copyright (C) 2007-2008 Gabor Juhos <juhosg at openwrt.org>
  *
  *  This code was based on the information of the ZyXEL's firmware
  *  image format written by Kolja Waschk, can be found at:
@@ -95,7 +95,8 @@ struct board_info {
        uint32_t flash_base;    /* flash base address */
        uint32_t flash_size;    /* board flash size */
        uint32_t code_start;    /* code start address */
-       uint32_t fw_offs;       /* offset of the firmware within the flash */
+       uint32_t romio_offs;    /* offset of the firmware within the flash */
+       uint32_t bootext_size;  /* maximum size of bootext block */
 };
 
 /*
@@ -121,11 +122,12 @@ int num_blocks = 0;
 #define ATHEROS_FLASH_BASE     0xBFC00000
 #define ATHEROS_CODE_START     0x80e00000
 
-#define BOARD(n, d, v, m, fb, fs, cs, fo) { \
-       .name = (n), .desc=(d), \
-       .vendor = (v), .model = (m), \
-       .flash_base = (fb), .flash_size = (fs)<<20, \
-       .code_start = (cs), .fw_offs = (fo) \
+#define BOARD(n, d, v, m, fb, fs, cs, fo) {            \
+       .name = (n), .desc=(d),                         \
+       .vendor = (v), .model = (m),                    \
+       .flash_base = (fb), .flash_size = (fs)<<20,     \
+       .code_start = (cs), .romio_offs = (fo),         \
+       .bootext_size = BOOTEXT_DEF_SIZE                \
        }
 
 #define ADMBOARD1(n, d, m, fs) BOARD(n, d, ZYNOS_VENDOR_ID_ZYXEL, m, \
@@ -138,7 +140,7 @@ int num_blocks = 0;
        AR7_FLASH_BASE, fs, AR7_CODE_START, 0x8000)
 
 #define ATHEROSBOARD1(n, d, m, fs) BOARD(n, d, ZYNOS_VENDOR_ID_ZYXEL, m, \
-       ATHEROS_FLASH_BASE, fs, ATHEROS_CODE_START, 0x8000)
+       ATHEROS_FLASH_BASE, fs, ATHEROS_CODE_START, 0x30000)
 
 static struct board_info boards[] = {
        /*
@@ -164,6 +166,18 @@ static struct board_info boards[] = {
        ADMBOARD1("P-335U",     "ZyXEL Prestige 335U", ZYNOS_MODEL_P_335U, 4),
        ADMBOARD1("P-335WT",    "ZyXEL Prestige 335WT", ZYNOS_MODEL_P_335WT, 4),
 
+       {
+               .name           = "P-2602HW-D1A",
+               .desc           = "ZyXEL P-2602HW-D1A",
+               .vendor         = ZYNOS_VENDOR_ID_ZYXEL,
+               .model          = ZYNOS_MODEL_P_2602HW_D1A,
+               .flash_base     = AR7_FLASH_BASE,
+               .flash_size     = 4*1024*1024,
+               .code_start     = 0x94008000,
+               .romio_offs     = 0x20000,
+               .bootext_size   = BOOTEXT_DEF_SIZE,
+       },
+
 #if 0
        /*
         * Texas Instruments AR7 based boards
@@ -193,7 +207,8 @@ static struct board_info boards[] = {
                .flash_base     = AR7_FLASH_BASE,
                .flash_size     = 8*1024*1024,
                .code_start     = 0x94014000,
-               .fw_offs        = 0x40000,
+               .romio_offs     = 0x40000,
+               .bootext_size   = BOOTEXT_DEF_SIZE,
        },
 
        /*
@@ -690,11 +705,13 @@ write_out_image(FILE *outfile)
        hdr.type = OBJECT_TYPE_BOOTEXT;
        hdr.flags = ROMBIN_FLAG_OCSUM;
 
+       offset = board->romio_offs;
+
        res = write_out_header(outfile, &hdr);
        if (res)
                return res;
 
-       offset = sizeof(hdr);
+       offset += sizeof(hdr);
 
        csum_init(&css);
        res = write_out_block(outfile, bootext_block, &css);
@@ -702,31 +719,45 @@ write_out_image(FILE *outfile)
                return res;
 
        offset += bootext_block->file_size;
+       if (offset > (board->romio_offs + board->bootext_size)) {
+               ERR("bootext file '%s' is too big", bootext_block->file_name);
+               return -1;
+       }
 
-       padlen = ALIGN(offset,MMAP_ALIGN) - offset;
+       padlen = ALIGN(offset, MMAP_ALIGN) - offset;
        res = write_out_padding(outfile, padlen, 0xFF, &css);
        if (res)
                return res;
 
        offset += padlen;
 
-       mmap.addr = board->flash_base + board->fw_offs + offset;
+       mmap.addr = board->flash_base + board->romio_offs + offset;
        hdr.mmap_addr = mmap.addr;
        res = write_out_mmap(outfile, &mmap, &css);
        if (res)
                return res;
 
        offset += MMAP_DATA_SIZE;
-       hdr.osize = offset - sizeof(hdr);
+       hdr.osize = offset - sizeof(hdr) - board->romio_offs;
        hdr.ocsum = csum_get(&css);
 
-       for (i=0; i < num_blocks; i++) {
+       if ((offset - board->romio_offs) < board->bootext_size) {
+               padlen = board->romio_offs + board->bootext_size - offset;
+               res = write_out_padding(outfile, padlen, 0xFF, NULL);
+               if (res)
+                       return res;
+               offset += padlen;
+
+               DBG(2, "bootext end at %08x", offset);
+       }
+
+       for (i = 0; i < num_blocks; i++) {
                block = &blocks[i];
 
                if (block->type == BLOCK_TYPE_BOOTEXT)
                        continue;
 
-               padlen = ALIGN(offset,block->align) - offset;
+               padlen = ALIGN(offset, block->align) - offset;
                res = write_out_padding(outfile, padlen, 0xFF, NULL);
                if (res)
                        return res;
@@ -887,7 +918,7 @@ calc_block_offsets(int type, uint32_t *offset)
                        continue;
 
                next_offs = ALIGN(*offset, block->align);
-               avail = board->flash_size - board->fw_offs - next_offs;
+               avail = board->flash_size - board->romio_offs - next_offs;
                if (next_offs + block->file_size > avail) {
                        ERR("file %s is too big, offset = %u, size=%u,"
                                " align = %u", block->file_name,
@@ -921,7 +952,7 @@ process_blocks(void)
                        return res;
        }
 
-       offset = board->fw_offs + bootext_block->file_size;
+       offset = board->romio_offs + bootext_block->file_size;
        res = calc_block_offsets(BLOCK_TYPE_RAW, &offset);
 
        return res;
@@ -989,7 +1020,6 @@ main(int argc, char *argv[])
                goto out;
        }
 
-
        if (process_blocks() != 0) {
                goto out;
        }
This page took 0.039875 seconds and 4 git commands to generate.