[brcm-2.4] fix Dell TrueMobile 2300 v1/v2 detection and network configuration (closes...
[openwrt.git] / tools / firmware-utils / src / mkzynfw.c
index 9009d50..b6cb7cf 100644 (file)
@@ -96,6 +96,7 @@ struct board_info {
        uint32_t flash_size;    /* board flash size */
        uint32_t code_start;    /* code start address */
        uint32_t romio_offs;    /* offset of the firmware within the flash */
        uint32_t flash_size;    /* board flash size */
        uint32_t code_start;    /* code start address */
        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 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), .romio_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, \
        }
 
 #define ADMBOARD1(n, d, m, fs) BOARD(n, d, ZYNOS_VENDOR_ID_ZYXEL, m, \
@@ -173,6 +175,7 @@ static struct board_info boards[] = {
                .flash_size     = 4*1024*1024,
                .code_start     = 0x94008000,
                .romio_offs     = 0x20000,
                .flash_size     = 4*1024*1024,
                .code_start     = 0x94008000,
                .romio_offs     = 0x20000,
+               .bootext_size   = BOOTEXT_DEF_SIZE,
        },
 
 #if 0
        },
 
 #if 0
@@ -205,6 +208,7 @@ static struct board_info boards[] = {
                .flash_size     = 8*1024*1024,
                .code_start     = 0x94014000,
                .romio_offs     = 0x40000,
                .flash_size     = 8*1024*1024,
                .code_start     = 0x94014000,
                .romio_offs     = 0x40000,
+               .bootext_size   = BOOTEXT_DEF_SIZE,
        },
 
        /*
        },
 
        /*
@@ -560,6 +564,15 @@ write_out_header(FILE *outfile, struct zyn_rombin_hdr *hdr)
        t.ccsum = HOST_TO_BE16(hdr->ccsum);
        t.mmap_addr = HOST_TO_BE32(hdr->mmap_addr);
 
        t.ccsum = HOST_TO_BE16(hdr->ccsum);
        t.mmap_addr = HOST_TO_BE32(hdr->mmap_addr);
 
+       DBG(2, "hdr.addr      = 0x%08x", hdr->addr);
+       DBG(2, "hdr.type      = 0x%02x", hdr->type);
+       DBG(2, "hdr.osize     = 0x%08x", hdr->osize);
+       DBG(2, "hdr.csize     = 0x%08x", hdr->csize);
+       DBG(2, "hdr.flags     = 0x%02x", hdr->flags);
+       DBG(2, "hdr.ocsum     = 0x%04x", hdr->ocsum);
+       DBG(2, "hdr.ccsum     = 0x%04x", hdr->ccsum);
+       DBG(2, "hdr.mmap_addr = 0x%08x", hdr->mmap_addr);
+
        return write_out_data(outfile, (uint8_t *)&t, sizeof(t), NULL);
 }
 
        return write_out_data(outfile, (uint8_t *)&t, sizeof(t), NULL);
 }
 
@@ -621,6 +634,35 @@ block_stat_file(struct fw_block *block)
 }
 
 
 }
 
 
+int
+read_magic(uint16_t *magic)
+{
+       FILE *f;
+       int res;
+
+       errno = 0;
+       f = fopen(bootext_block->file_name,"r");
+       if (errno) {
+               ERRS("unable to open file: %s", bootext_block->file_name);
+               return -1;
+       }
+
+       errno = 0;
+       fread(magic, 2, 1, f);
+       if (errno != 0) {
+               ERRS("unable to read from file: %s", bootext_block->file_name);
+               res = -1;
+               goto err;
+       }
+
+       res = 0;
+
+err:
+       fclose(f);
+       return res;
+}
+
+
 int
 write_out_file(FILE *outfile, char *name, size_t len, struct csum_state *css)
 {
 int
 write_out_file(FILE *outfile, char *name, size_t len, struct csum_state *css)
 {
@@ -694,6 +736,8 @@ write_out_image(FILE *outfile)
        int i, res;
        uint32_t offset;
        uint32_t padlen;
        int i, res;
        uint32_t offset;
        uint32_t padlen;
+       uint16_t csum;
+       uint16_t t;
 
        /* setup header fields */
        memset(&hdr, 0, sizeof(hdr));
 
        /* setup header fields */
        memset(&hdr, 0, sizeof(hdr));
@@ -701,11 +745,13 @@ write_out_image(FILE *outfile)
        hdr.type = OBJECT_TYPE_BOOTEXT;
        hdr.flags = ROMBIN_FLAG_OCSUM;
 
        hdr.type = OBJECT_TYPE_BOOTEXT;
        hdr.flags = ROMBIN_FLAG_OCSUM;
 
+       offset = board->romio_offs;
+
        res = write_out_header(outfile, &hdr);
        if (res)
                return res;
 
        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);
 
        csum_init(&css);
        res = write_out_block(outfile, bootext_block, &css);
@@ -713,42 +759,81 @@ write_out_image(FILE *outfile)
                return res;
 
        offset += bootext_block->file_size;
                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;
 
        res = write_out_padding(outfile, padlen, 0xFF, &css);
        if (res)
                return res;
 
        offset += padlen;
 
-       mmap.addr = board->flash_base + board->romio_offs + offset;
-       hdr.mmap_addr = mmap.addr;
+       mmap.addr = board->flash_base + offset;
        res = write_out_mmap(outfile, &mmap, &css);
        if (res)
                return res;
 
        offset += MMAP_DATA_SIZE;
        res = write_out_mmap(outfile, &mmap, &css);
        if (res)
                return res;
 
        offset += MMAP_DATA_SIZE;
-       hdr.osize = offset - sizeof(hdr);
-       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, &css);
+               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;
 
                block = &blocks[i];
 
                if (block->type == BLOCK_TYPE_BOOTEXT)
                        continue;
 
-               padlen = ALIGN(offset,block->align) - offset;
-               res = write_out_padding(outfile, padlen, 0xFF, NULL);
+               padlen = ALIGN(offset, block->align) - offset;
+               res = write_out_padding(outfile, padlen, 0xFF, &css);
                if (res)
                        return res;
                offset += padlen;
 
                if (res)
                        return res;
                offset += padlen;
 
-               res = write_out_block(outfile, block, NULL);
+               res = write_out_block(outfile, block, &css);
                if (res)
                        return res;
                offset += block->file_size;
        }
 
                if (res)
                        return res;
                offset += block->file_size;
        }
 
+       padlen = ALIGN(offset, 4) - offset;
+       res = write_out_padding(outfile, padlen, 0xFF, &css);
+       if (res)
+               return res;
+       offset += padlen;
+
+       csum = csum_get(&css);
+       hdr.mmap_addr = mmap.addr;
+       hdr.osize = 2;
+
+       res = read_magic(&hdr.ocsum);
+       if (res)
+               return res;
+       hdr.ocsum = BE16_TO_HOST(hdr.ocsum);
+
+       if (csum <= hdr.ocsum)
+               t = hdr.ocsum - csum;
+       else
+               t = hdr.ocsum - csum - 1;
+
+       DBG(2, "ocsum=%04x, csum=%04x, fix=%04x", hdr.ocsum, csum, t);
+
+       t = HOST_TO_BE16(t);
+       res = write_out_data(outfile, (uint8_t *)&t, 2, NULL);
+       if (res)
+               return res;
+
+
        res = write_out_header(outfile, &hdr);
 
        return res;
        res = write_out_header(outfile, &hdr);
 
        return res;
@@ -864,7 +949,7 @@ parse_opt_block(char ch, char *arg)
                }
        }
 
                }
        }
 
-       if(block->type == BLOCK_TYPE_BOOTEXT)
+       if (block->type == BLOCK_TYPE_BOOTEXT)
                return 0;
 
        p = argv[i++];
                return 0;
 
        p = argv[i++];
@@ -1000,7 +1085,6 @@ main(int argc, char *argv[])
                goto out;
        }
 
                goto out;
        }
 
-
        if (process_blocks() != 0) {
                goto out;
        }
        if (process_blocks() != 0) {
                goto out;
        }
This page took 0.034881 seconds and 4 git commands to generate.