Changeset 24011


Ignore:
Timestamp:
2010-11-16T07:46:53+01:00 (7 years ago)
Author:
cshore
Message:

[tools/firmware-utils] imagetag: Significantly updated brcm63xx imagetag writing tool.

  • Rewrote commandline parsing code using gengetopt
    • We now get long options
    • We have more options including use of the info section for

board information (e.g. to add the same boardid but
different GPIOs on different routers)

  • Added back the ability to write stock images (this is useful, for example,

when copying the firmware from the in-memory flash, and then being
able to create an image that will let you revert to/test stock firmware

  • Fixed copying of CRCs to use memcpy instead of strncpy (strncpy stops at 0)
  • Added ability to use all sections of the imagetag, including custom magic

signatures (e.g. for the Telsey router I'm adding soon), info sections,

and reserved sections

  • Added putting the router type (as defined in the image generating Makefile)

into the info1 section and the filesystem type in the info2 section.
This will be used by mtd (when I add the code) to return the name of
image used to flash this router. (As requested by Jo, as well as being
useful for same boardid different board scenario described above).

Location:
trunk
Files:
3 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/target/linux/brcm63xx/image/Makefile

    r20834 r24011  
    3131        # Generate the tagged image 
    3232        $(STAGING_DIR_HOST)/bin/imagetag -i $(KDIR)/vmlinux.lzma.cfe -f $(KDIR)/root.$(1) \ 
    33                 -o $(BIN_DIR)/openwrt-$(4)-$(1)-cfe.bin \ 
    34                 -b $(2) -c $(3) -e $(LOADADDR) -l $(LOADADDR) \ 
    35                 -r "$(5)" $(6) 
    36 #               -b $(2) -c $(3) -e $(KERNEL_ENTRY) -l $(LOADADDR) 
    37  
     33                --output $(BIN_DIR)/openwrt-$(4)-$(1)-cfe.bin \ 
     34                --boardid $(2) --chipid $(3) --entry $(KERNEL_ENTRY) \ 
     35                --load-addr $(LOADADDR) --rsa-signature "$(5)" \ 
     36                --info1 "$(4) $(REVISION)" --info2 $(1) \ 
     37                $(6) $(7) $(8) $(9) 
    3838endef 
    3939 
     
    4141        # Generate the tagged image 
    4242        $(STAGING_DIR_HOST)/bin/imagetag -i $(KDIR)/vmlinux.lzma.cfe -f $(KDIR)/root.$(1) \ 
    43                 -o $(BIN_DIR)/openwrt-$(5)-$(1)-cfe.bin \ 
    44                 -b $(2) -c $(3) -e $(LOADADDR) -l $(LOADADDR) \ 
    45                 -v 8 -m IMAGE -k 0x20000 -n $(4) 
     43                --output $(BIN_DIR)/openwrt-$(5)-$(1)-cfe.bin \ 
     44                --boardid $(2) --chipid $(3) --entry $(LOADADDR) \ 
     45                --load-addr $(LOADADDR) --tag-version 8 \ 
     46                --signature2 IMAGE --block-size 0x20000 \ 
     47                --image-offset $(4) --info1 "$(5) $(REVISION)" --info2 $(1) 
    4648endef 
    4749 
     
    4951        # Generate the tagged image 
    5052        $(STAGING_DIR_HOST)/bin/imagetag -i $(KDIR)/vmlinux.lzma.cfe -f $(KDIR)/root.$(1) \ 
    51                 -o $(BIN_DIR)/openwrt-$(5)-$(1)-cfe.bin \ 
    52                 -b $(2) -c $(3) -e $(LOADADDR) -l $(LOADADDR) \ 
    53                 -k 0x20000 -n $(4) 
     53                --output $(BIN_DIR)/openwrt-$(5)-$(1)-cfe.bin \ 
     54                --boardid $(2) --chipid $(3) --entry $(LOADADDR) \ 
     55                --load-addr $(LOADADDR) --block-size 0x20000 \ 
     56                --image-offset $(4) --info1 "$(5) $(REVISION)" --info2 $(1) 
    5457endef 
    55  
    5658 
    5759define Image/Build/RedBoot 
     
    107109        # Various routers 
    108110        $(call Image/Build/CFE,$(1),96345GW2,6345,96345GW2-generic) 
    109         $(call Image/Build/CFE,$(1),96345GW2,6345,96348GW2-bc221,,-y 5) 
     111        $(call Image/Build/CFE,$(1),96345GW2,6345,96348GW2-bc221,,--layoutver 5) 
    110112        $(call Image/Build/CFE,$(1),96345GW2,6345,92345GW2-revision,OpenWRT-$(REVISION)) 
    111113        $(call Image/Build/CFE,$(1),96348GW,6348,96348GW-generic,,) 
    112         $(call Image/Build/CFE,$(1),96348GW,6348,96348GW-bc221,,-y 5) 
     114        $(call Image/Build/CFE,$(1),96348GW,6348,96348GW-bc221,,--layoutver 5) 
    113115        $(call Image/Build/CFE,$(1),6338GW,6338,6338GW-generic,,) 
    114116        $(call Image/Build/CFE,$(1),6338W,6338,6338W-generic,,) 
    115117 
    116118        # BT Voyager V210_BTR 
    117         $(call Image/Build/CFE,$(1),V210_BB,6348,BTV210_BTR,,-y 5) 
     119        $(call Image/Build/CFE,$(1),V210_BB,6348,BTV210_BTR,,--layoutver 5) 
    118120        # BT Voyager V210_ROI, V210_WB 
    119         $(call Image/Build/CFE,$(1),V210,6348,BTV210_ROI_WB,,-y 5) 
     121        $(call Image/Build/CFE,$(1),V210,6348,BTV210_ROI_WB,,--layoutver 5) 
    120122        # BT Voyager V2091_BTR 
    121         $(call Image/Build/CFE,$(1),V2091_BB,6348,BTV2091_BTR,,y 5) 
     123        $(call Image/Build/CFE,$(1),V2091_BB,6348,BTV2091_BTR,,--layoutver 5) 
    122124        # BT Voyager V2091_ROI, V2091_WB 
    123         $(call Image/Build/CFE,$(1),V2091,6348,BTV2091_ROI_WB,,-y 5) 
     125        $(call Image/Build/CFE,$(1),V2091,6348,BTV2091_ROI_WB,,--layoutver 5) 
    124126        # BT Voyager V220V, V220V_MGCP_BTR 
    125         $(call Image/Build/CFE,$(1),RTA1052V,6348,BTV220V_MGCP_BTR,,-y 5) 
     127        $(call Image/Build/CFE,$(1),RTA1052V,6348,BTV220V_MGCP_BTR,,--layoutver 5) 
    126128        # BT Voyager V2110, V2110_AA, V2110_ROI 
    127         $(call Image/Build/CFE,$(1),V2110,6348,BTV2110,,-y 5) 
     129        $(call Image/Build/CFE,$(1),V2110,6348,BTV2110,,--layoutver 5) 
    128130        # BT Voyager V2500V, V2500V_SIP_CLUB, V2500V_AA 
    129         $(call Image/Build/CFE,$(1),V2500V_BB,6348,BTV2500V,,-y 5) 
     131        $(call Image/Build/CFE,$(1),V2500V_BB,6348,BTV2500V,,--layoutver 5) 
    130132        # RTA1025W_16 (numerous routers) 
    131         $(call Image/Build/CFE,$(1),RTA1025W_16,6348,RTA1025W_16,,-y 5) 
     133        $(call Image/Build/CFE,$(1),RTA1025W_16,6348,RTA1025W_16,,--layoutver 5) 
    132134        # Tecom GW6000 
    133135        $(call Image/Build/CFE,$(1),96348GW,6348,GW6000) 
     
    167169        $(call Image/Build/CFEAGPF,$(1),DWV-S0,6358,0x10000,A226G-cfe) 
    168170        $(call Image/Build/CFEAGPF,$(1),DWV-S0,6358,0x10000,A226G) 
    169          
     171 
    170172        # RG100A,DB120 etc. 
    171173        $(call Image/Build/RG100A,$(1),96358VW2,6358,0x20000,RG100A_DB120) 
  • trunk/tools/firmware-utils/Makefile

    r22883 r24011  
    1515        $(CC) $(HOST_CFLAGS) -include endian.h -o $(HOST_BUILD_DIR)/bin/$(firstword $(1)) $(foreach src,$(1),src/$(src).c) $(2) 
    1616endef 
    17  
    1817 
    1918define Host/Compile 
     
    3433        $(call cc,mkfwimage,-lz) 
    3534        $(call cc,mkfwimage2,-lz) 
    36         $(call cc,imagetag) 
     35        $(call cc,imagetag imagetag_cmdline) 
    3736        $(call cc,add_header) 
    3837        $(call cc,makeamitbin) 
  • trunk/tools/firmware-utils/src/imagetag.c

    r24000 r24011  
    55 * 
    66 * Copyright (C) 2008 Axel Gembe <ago@bastart.eu.org> 
    7  * Copyright (C) 2009 Daniel Dickinson <crazycshore@gmail.com> 
     7 * Copyright (C) 2009-2010 Daniel Dickinson <openwrt@cshore.neomailbox.net> 
    88 */ 
    99 
     
    1818 
    1919#include "bcm_tag.h" 
    20  
    21 #define IMAGETAG_MAGIC1                 "Broadcom Corporatio" 
    22 #define IMAGETAG_MAGIC2                 "ver. 2.0" 
    23 #define IMAGETAG_VER                    "6" 
    24 #define IMAGETAG_DEFAULT_LOADADDR       0x80010000 
    25 #define DEFAULT_FW_OFFSET               0x10000 
    26 #define DEFAULT_FLASH_START             0xBFC00000 
    27 #define DEFAULT_FLASH_BS                (64 * 1024) 
     20#include "imagetag_cmdline.h" 
     21 
    2822#define DEADCODE                        0xDEADC0DE 
    29  
    30 union int2char { 
    31   uint32_t input; 
    32   char output[4]; 
    33 }; 
    34  
    35 /* Convert uint32_t CRC to bigendian and copy it into a character array */ 
    36 #define int2tag(tag, value)  intchar.input = htonl(value);      \ 
    37           memcpy(tag, intchar.output, sizeof(union int2char)) 
    3823 
    3924/* Kernel header */ 
     
    8166}; 
    8267 
     68void int2tag(char *tag, uint32_t value) { 
     69  uint32_t network = htonl(value); 
     70  memcpy(tag, (char *)(&network), 4); 
     71} 
     72 
    8373uint32_t crc32(uint32_t crc, uint8_t *data, size_t len) 
    8474{ 
     
    127117} 
    128118 
    129 int tagfile(const char *kernel, const char *rootfs, const char *bin, 
    130             const char *boardid, const char *chipid, const uint32_t fwaddr, 
    131             const uint32_t loadaddr, const uint32_t entry, 
    132             const char *ver, const char *magic2, const uint32_t flash_bs, 
    133             const char *rsignature, const char *layoutver) 
     119int tagfile(const char *kernel, const char *rootfs, const char *bin, \ 
     120                        const struct gengetopt_args_info *args, \ 
     121                        uint32_t flash_start, uint32_t image_offset, \ 
     122                        uint32_t block_size, uint32_t load_address, uint32_t entry) 
    134123{ 
    135124        struct bcm_tag tag; 
    136125        struct kernelhdr khdr; 
    137         FILE *kernelfile = NULL, *rootfsfile = NULL, *binfile; 
    138         size_t kerneloff, kernellen, rootfsoff, rootfslen, read, imagelen, rootfsoffpadlen, kernelfslen; 
     126        FILE *kernelfile = NULL, *rootfsfile = NULL, *binfile = NULL, *cfefile = NULL; 
     127        size_t cfeoff, cfelen, kerneloff, kernellen, rootfsoff, rootfslen, \ 
     128          read, imagelen, rootfsoffpadlen = 0, kernelfslen, kerneloffpadlen = 0, oldrootfslen; 
    139129        uint8_t readbuf[1024]; 
    140130        uint32_t imagecrc = IMAGETAG_CRC_START; 
     
    142132        uint32_t rootfscrc = IMAGETAG_CRC_START; 
    143133        uint32_t kernelfscrc = IMAGETAG_CRC_START; 
     134        uint32_t fwaddr = 0; 
     135        uint8_t crc_val; 
    144136        const uint32_t deadcode = htonl(DEADCODE); 
    145         union int2char intchar; 
    146         int i; 
    147         int is_pirelli = 0; 
     137        int i; 
     138        int is_pirelli = 0; 
     139 
    148140 
    149141        memset(&tag, 0, sizeof(struct bcm_tag)); 
    150  
    151         if (strlen(boardid) >= sizeof(tag.boardid)) { 
    152                 fprintf(stderr, "Board id is too long!\n"); 
    153                 return 1; 
    154         } 
    155  
    156         /* Likewise chipid */ 
    157         if (strlen(chipid) >= sizeof(tag.chipid)) { 
    158                 fprintf(stderr, "Chip id is too long!\n"); 
    159                 return 1; 
    160         } 
    161142 
    162143        if (!kernel || !rootfs) { 
     
    179160        } 
    180161 
    181         /* Build the kernel address and length (doesn't need to be aligned, read only) */ 
    182         kerneloff = fwaddr + sizeof(tag); 
    183         kernellen = getlen(kernelfile); 
    184  
    185         /* Build the kernel header */ 
    186         khdr.loadaddr   = htonl(loadaddr); 
    187         khdr.entry      = htonl(entry); 
    188         khdr.lzmalen    = htonl(kernellen); 
    189  
    190         /* Increase the kernel size by the header size */ 
    191         kernellen += sizeof(khdr); 
    192  
    193         /* Build the rootfs address and length (start and end do need to be aligned on flash erase block boundaries */ 
    194         rootfsoff = kerneloff + kernellen; 
    195         rootfsoff = (rootfsoff % flash_bs) > 0 ? (((rootfsoff / flash_bs) + 1) * flash_bs) : rootfsoff; 
    196         rootfslen = getlen(rootfsfile); 
    197         rootfslen = ( (rootfslen % flash_bs) > 0 ? (((rootfslen / flash_bs) + 1) * flash_bs) : rootfslen ); 
    198         imagelen = rootfsoff + rootfslen - kerneloff + sizeof(deadcode); 
    199         rootfsoffpadlen = rootfsoff - (kerneloff + kernellen); 
    200  
    201         /* Seek to the start of the kernel */ 
    202         fseek(binfile, kerneloff - fwaddr, SEEK_SET); 
    203  
    204         /* Write the kernel header */ 
    205         fwrite(&khdr, sizeof(khdr), 1, binfile); 
    206  
    207         /* Write the kernel */ 
    208         while (kernelfile && !feof(kernelfile) && !ferror(kernelfile)) { 
     162        if ((args->cfe_given) && (args->cfe_arg)) { 
     163          if (!(cfefile = fopen(args->cfe_arg, "rb"))) { 
     164                fprintf(stderr, "Unable to open CFE file \"%s\"\n", args->cfe_arg); 
     165          } 
     166        } 
     167 
     168        fwaddr = flash_start + image_offset; 
     169        if (cfefile) { 
     170          cfeoff = flash_start;            
     171          cfelen = getlen(cfefile); 
     172          /* Seek to the start of the file after tag */ 
     173          fseek(binfile, sizeof(tag), SEEK_SET); 
     174           
     175          /* Write the cfe */ 
     176          while (cfefile && !feof(cfefile) && !ferror(cfefile)) { 
     177                read = fread(readbuf, sizeof(uint8_t), sizeof(readbuf), cfefile); 
     178                fwrite(readbuf, sizeof(uint8_t), read, binfile); 
     179          } 
     180 
     181        } else { 
     182          cfeoff = 0; 
     183          cfelen = 0; 
     184        } 
     185 
     186        if (!args->root_first_flag) { 
     187          /* Build the kernel address and length (doesn't need to be aligned, read only) */ 
     188          kerneloff = fwaddr + sizeof(tag); 
     189           
     190          kernellen = getlen(kernelfile); 
     191           
     192          if (!args->kernel_file_has_header_flag) { 
     193                /* Build the kernel header */ 
     194                khdr.loadaddr   = htonl(load_address); 
     195                khdr.entry      = htonl(entry); 
     196                khdr.lzmalen    = htonl(kernellen); 
     197                 
     198                /* Increase the kernel size by the header size */ 
     199                kernellen += sizeof(khdr);         
     200          } 
     201           
     202          /* Build the rootfs address and length (start and end do need to be aligned on flash erase block boundaries */ 
     203          rootfsoff = kerneloff + kernellen; 
     204          rootfsoff = (rootfsoff % block_size) > 0 ? (((rootfsoff / block_size) + 1) * block_size) : rootfsoff; 
     205          rootfslen = getlen(rootfsfile); 
     206          rootfslen = ( (rootfslen % block_size) > 0 ? (((rootfslen / block_size) + 1) * block_size) : rootfslen ); 
     207          imagelen = rootfsoff + rootfslen - kerneloff + sizeof(deadcode); 
     208          rootfsoffpadlen = rootfsoff - (kerneloff + kernellen); 
     209           
     210          /* Seek to the start of the kernel */ 
     211          fseek(binfile, kerneloff - fwaddr + cfelen, SEEK_SET); 
     212           
     213          /* Write the kernel header */ 
     214          fwrite(&khdr, sizeof(khdr), 1, binfile); 
     215           
     216          /* Write the kernel */ 
     217          while (kernelfile && !feof(kernelfile) && !ferror(kernelfile)) { 
    209218                read = fread(readbuf, sizeof(uint8_t), sizeof(readbuf), kernelfile); 
    210219                fwrite(readbuf, sizeof(uint8_t), read, binfile); 
    211         } 
    212  
    213         /* Write the RootFS */ 
    214         fseek(binfile, rootfsoff - fwaddr, SEEK_SET); 
    215         while (rootfsfile && !feof(rootfsfile) && !ferror(rootfsfile)) { 
     220          } 
     221 
     222          /* Write the RootFS */ 
     223          fseek(binfile, rootfsoff - fwaddr + cfelen, SEEK_SET); 
     224          while (rootfsfile && !feof(rootfsfile) && !ferror(rootfsfile)) { 
    216225                read = fread(readbuf, sizeof(uint8_t), sizeof(readbuf), rootfsfile); 
    217226                fwrite(readbuf, sizeof(uint8_t), read, binfile); 
    218         } 
    219  
    220         /* Align image to specified erase block size and append deadc0de */ 
    221         printf("Data alignment to %dk with 'deadc0de' appended\n", flash_bs/1024); 
    222         fseek(binfile, rootfsoff + rootfslen - fwaddr, SEEK_SET); 
    223         fwrite(&deadcode, sizeof(uint32_t), 1, binfile); 
    224  
    225         /* Flush the binfile buffer so that when we read from file, it contains 
    226          * everything in the buffer 
    227          */ 
    228         fflush(binfile); 
    229  
    230         /* Compute the crc32 of the entire image (deadC0de included) */ 
    231         imagecrc = compute_crc32(imagecrc, binfile, kerneloff - fwaddr, imagelen); 
    232         /* Compute the crc32 of the kernel and padding between kernel and rootfs) */ 
    233         kernelcrc = compute_crc32(kernelcrc, binfile, kerneloff - fwaddr, kernellen + rootfsoffpadlen); 
    234         /* Compute the crc32 of the kernel and padding between kernel and rootfs) */ 
    235         kernelfscrc = compute_crc32(kernelfscrc, binfile, kerneloff - fwaddr, kernellen + rootfsoffpadlen + rootfslen + sizeof(deadcode)); 
    236         /* Compute the crc32 of the flashImageStart to rootLength. 
    237          * The broadcom firmware assumes the rootfs starts the image, 
    238          * therefore uses the rootfs start to determine where to flash 
    239          * the image.  Since we have the kernel first we have to give 
    240          * it the kernel address, but the crc uses the length 
    241          * associated with this address, which is added to the kernel 
    242          * length to determine the length of image to flash and thus 
    243          * needs to be rootfs + deadcode 
    244          */ 
    245         rootfscrc = compute_crc32(rootfscrc, binfile, kerneloff - fwaddr, rootfslen + sizeof(deadcode)); 
     227          } 
     228 
     229          /* Align image to specified erase block size and append deadc0de */ 
     230          printf("Data alignment to %dk with 'deadc0de' appended\n", block_size/1024); 
     231          fseek(binfile, rootfsoff + rootfslen - fwaddr + cfelen, SEEK_SET); 
     232          fwrite(&deadcode, sizeof(uint32_t), 1, binfile); 
     233 
     234          /* Flush the binfile buffer so that when we read from file, it contains 
     235           * everything in the buffer 
     236           */ 
     237          fflush(binfile); 
     238 
     239          /* Compute the crc32 of the entire image (deadC0de included) */ 
     240          imagecrc = compute_crc32(imagecrc, binfile, kerneloff - fwaddr + cfelen, imagelen); 
     241          /* Compute the crc32 of the kernel and padding between kernel and rootfs) */ 
     242          kernelcrc = compute_crc32(kernelcrc, binfile, kerneloff - fwaddr + cfelen, kernellen + rootfsoffpadlen); 
     243          /* Compute the crc32 of the kernel and padding between kernel and rootfs) */ 
     244          kernelfscrc = compute_crc32(kernelfscrc, binfile, kerneloff - fwaddr + cfelen, kernellen + rootfsoffpadlen + rootfslen + sizeof(deadcode)); 
     245          /* Compute the crc32 of the flashImageStart to rootLength. 
     246           * The broadcom firmware assumes the rootfs starts the image, 
     247           * therefore uses the rootfs start to determine where to flash 
     248           * the image.  Since we have the kernel first we have to give 
     249           * it the kernel address, but the crc uses the length 
     250           * associated with this address, which is added to the kernel 
     251           * length to determine the length of image to flash and thus 
     252           * needs to be rootfs + deadcode 
     253           */ 
     254          rootfscrc = compute_crc32(rootfscrc, binfile, kerneloff - fwaddr + cfelen, rootfslen + sizeof(deadcode)); 
     255 
     256        } else { 
     257          /* Build the kernel address and length (doesn't need to be aligned, read only) */ 
     258          rootfsoff = fwaddr + sizeof(tag); 
     259          oldrootfslen = getlen(rootfsfile); 
     260          rootfslen = oldrootfslen; 
     261          rootfslen = ( (rootfslen % block_size) > 0 ? (((rootfslen / block_size) + 1) * block_size) : rootfslen ); 
     262          kerneloffpadlen = rootfslen - oldrootfslen; 
     263 
     264          kerneloff = rootfsoff + rootfslen; 
     265          kernellen = getlen(kernelfile); 
     266 
     267          imagelen = cfelen + rootfslen + kernellen; 
     268           
     269          /* Seek to the start of the kernel */ 
     270          fseek(binfile, kerneloff - fwaddr + cfelen, SEEK_SET); 
     271           
     272          if (!args->kernel_file_has_header_flag) { 
     273                /* Build the kernel header */ 
     274                khdr.loadaddr   = htonl(load_address); 
     275                khdr.entry      = htonl(entry); 
     276                khdr.lzmalen    = htonl(kernellen); 
     277                 
     278                /* Write the kernel header */ 
     279                fwrite(&khdr, sizeof(khdr), 1, binfile); 
     280           
     281                /* Increase the kernel size by the header size */ 
     282                kernellen += sizeof(khdr);         
     283          } 
     284           
     285          /* Write the kernel */ 
     286          while (kernelfile && !feof(kernelfile) && !ferror(kernelfile)) { 
     287                read = fread(readbuf, sizeof(uint8_t), sizeof(readbuf), kernelfile); 
     288                fwrite(readbuf, sizeof(uint8_t), read, binfile); 
     289          } 
     290 
     291          /* Write the RootFS */ 
     292          fseek(binfile, rootfsoff - fwaddr + cfelen, SEEK_SET); 
     293          while (rootfsfile && !feof(rootfsfile) && !ferror(rootfsfile)) { 
     294                read = fread(readbuf, sizeof(uint8_t), sizeof(readbuf), rootfsfile); 
     295                fwrite(readbuf, sizeof(uint8_t), read, binfile); 
     296          } 
     297 
     298          /* Flush the binfile buffer so that when we read from file, it contains 
     299           * everything in the buffer 
     300           */ 
     301          fflush(binfile); 
     302 
     303          /* Compute the crc32 of the entire image (deadC0de included) */ 
     304          imagecrc = compute_crc32(imagecrc, binfile, sizeof(tag), imagelen); 
     305          /* Compute the crc32 of the kernel and padding between kernel and rootfs) */ 
     306          kernelcrc = compute_crc32(kernelcrc, binfile, kerneloff - fwaddr + cfelen, kernellen + rootfsoffpadlen); 
     307          kernelfscrc = compute_crc32(kernelfscrc, binfile, rootfsoff - fwaddr + cfelen, kernellen + rootfslen); 
     308          rootfscrc = compute_crc32(rootfscrc, binfile, rootfsoff - fwaddr + cfelen, rootfslen); 
     309        } 
    246310 
    247311        /* Close the files */ 
     312        if (cfefile) { 
     313          fclose(cfefile); 
     314        } 
    248315        fclose(kernelfile); 
    249316        fclose(rootfsfile); 
    250317 
    251318        /* Build the tag */ 
    252         strncpy(tag.tagVersion, ver, TAGVER_LEN); 
    253         strncpy(tag.sig_1, IMAGETAG_MAGIC1, sizeof(tag.sig_1) - 1); 
    254         strncpy(tag.sig_2, magic2, sizeof(tag.sig_2) - 1); 
    255         strcpy(tag.chipid, chipid); 
    256         strcpy(tag.boardid, boardid); 
     319        strncpy(tag.tagVersion, args->tag_version_arg, sizeof(tag.tagVersion) - 1); 
     320        strncpy(tag.sig_1, args->signature_arg, sizeof(tag.sig_1) - 1); 
     321        strncpy(tag.sig_2, args->signature2_arg, sizeof(tag.sig_2) - 1); 
     322        strncpy(tag.chipid, args->chipid_arg, sizeof(tag.chipid) - 1); 
     323        strncpy(tag.boardid, args->boardid_arg, sizeof(tag.boardid) - 1); 
    257324        strcpy(tag.big_endian, "1"); 
    258325        sprintf(tag.totalLength, "%lu", imagelen); 
    259326 
    260         /* We don't include CFE */ 
    261         strcpy(tag.cfeAddress, "0"); 
    262         strcpy(tag.cfeLength, "0"); 
    263  
    264         sprintf(tag.kernelAddress, "%lu", kerneloff); 
     327        if (args->cfe_given) { 
     328          sprintf(tag.cfeAddress, "%lu", flash_start); 
     329          sprintf(tag.cfeLength, "%lu", cfelen); 
     330        } else { 
     331          /* We don't include CFE */ 
     332          strcpy(tag.cfeAddress, "0"); 
     333          strcpy(tag.cfeLength, "0"); 
     334        } 
     335 
     336        sprintf(tag.kernelAddress, "%lu", kerneloff); 
    265337        sprintf(tag.kernelLength, "%lu", kernellen + rootfsoffpadlen); 
    266         sprintf(tag.flashImageStart, "%lu", kerneloff); 
    267         sprintf(tag.rootLength, "%lu", rootfslen + sizeof(deadcode)); 
    268  
    269         if (rsignature) { 
    270             strncpy(tag.rsa_signature, rsignature, RSASIG_LEN); 
    271         } 
    272  
    273         if (layoutver) { 
    274             strncpy(tag.flashLayoutVer, layoutver, TAGLAYOUT_LEN); 
     338 
     339        if (args->root_first_flag) { 
     340          sprintf(tag.flashImageStart, "%lu", rootfsoff); 
     341          sprintf(tag.rootLength, "%lu", rootfslen);       
     342        } else { 
     343          sprintf(tag.flashImageStart, "%lu", kerneloff); 
     344          sprintf(tag.rootLength, "%lu", rootfslen + sizeof(deadcode)); 
     345        } 
     346 
     347        if (args->rsa_signature_given) { 
     348            strncpy(tag.rsa_signature, args->rsa_signature_arg, RSASIG_LEN); 
     349        } 
     350 
     351        if (args->layoutver_given) { 
     352            strncpy(tag.flashLayoutVer, args->layoutver_arg, TAGLAYOUT_LEN); 
     353        } 
     354 
     355        if (args->info1_given) { 
     356          strncpy(tag.information1, args->info1_arg, TAGINFO1_LEN); 
     357        } 
     358 
     359        if (args->info2_given) { 
     360          strncpy(tag.information2, args->info2_arg, TAGINFO2_LEN); 
     361        } 
     362 
     363        if (args->reserved1_given) { 
     364          strncpy(tag.reserved1, args->reserved1_arg, 8); 
     365        } 
     366 
     367        if (args->reserved2_given) { 
     368          strncpy(tag.reserved2, args->reserved2_arg, 16); 
     369        } 
     370 
     371        if (args->altinfo_given) { 
     372          strncpy(&tag.information1[0], args->altinfo_arg, ALTTAGINFO_LEN); 
     373        } 
     374 
     375        if (args->second_image_flag_given) { 
     376          if (strncmp(args->second_image_flag_arg, "2", DUALFLAG_LEN) != 0) {            
     377                strncpy(tag.dualImage, args->second_image_flag_arg, DUALFLAG_LEN); 
     378          } 
     379        } 
     380 
     381        if (args->inactive_given) { 
     382          if (strncmp(args->inactive_arg, "2", INACTIVEFLAG_LEN) != 0) {                 
     383                strncpy(tag.inactiveFlag, args->second_image_flag_arg, INACTIVEFLAG_LEN); 
     384          } 
    275385        } 
    276386 
    277387        for (i = 0; i < NUM_PIRELLI; i++) { 
    278                 if (strncmp(boardid, pirellitab[i], BOARDID_LEN) == 0) { 
     388                if (strncmp(args->boardid_arg, pirellitab[i], BOARDID_LEN) == 0) { 
    279389                        is_pirelli = 1; 
    280390                        break; 
     
    283393 
    284394        if ( !is_pirelli ) { 
    285                 int2tag(tag.imageCRC, imagecrc); 
     395          int2tag(tag.imageCRC, kernelfscrc); 
    286396        } else { 
    287                 int2tag(tag.imageCRC, kernelcrc); 
    288         } 
    289         int2tag(tag.kernelCRC, kernelcrc); 
    290         int2tag(tag.rootfsCRC, rootfscrc); 
     397          int2tag(tag.imageCRC, kernelcrc); 
     398        } 
     399 
     400        int2tag(&(tag.rootfsCRC[0]), rootfscrc); 
     401        int2tag(tag.kernelCRC, kernelcrc); 
    291402        int2tag(tag.fskernelCRC, kernelfscrc); 
    292403        int2tag(tag.headerCRC, crc32(IMAGETAG_CRC_START, (uint8_t*)&tag, sizeof(tag) - 20)); 
     
    295406        fwrite(&tag, sizeof(uint8_t), sizeof(tag), binfile); 
    296407 
     408    fflush(binfile); 
    297409        fclose(binfile); 
    298410 
     
    302414int main(int argc, char **argv) 
    303415{ 
    304         int c, i; 
    305         char *kernel, *rootfs, *bin, *boardid, *chipid, *magic2, *ver, *tagid, *rsignature, *layoutver; 
    306         uint32_t flashstart, fwoffset, loadaddr, entry; 
    307         uint32_t fwaddr, flash_bs; 
    308         int tagidfound = 0; 
    309  
    310         kernel = rootfs = bin = boardid = chipid = magic2 = ver = rsignature = layoutver = NULL; 
    311         entry = 0; 
    312  
    313         flashstart = DEFAULT_FLASH_START; 
    314         fwoffset = DEFAULT_FW_OFFSET; 
    315         loadaddr = IMAGETAG_DEFAULT_LOADADDR; 
    316         flash_bs = DEFAULT_FLASH_BS; 
    317  
    318         printf("Broadcom image tagger - v1.0.0\n"); 
     416    int c, i; 
     417        char *kernel, *rootfs, *bin; 
     418        uint32_t flash_start, image_offset, block_size, load_address, entry; 
     419        flash_start = image_offset = block_size = load_address = entry = 0; 
     420        struct gengetopt_args_info parsed_args; 
     421 
     422        kernel = rootfs = bin = NULL; 
     423 
     424        if (cmdline_parser(argc, argv, &parsed_args)) { 
     425          exit(1); 
     426        } 
     427 
     428        printf("Broadcom 63xx image tagger - v2.0.0\n"); 
    319429        printf("Copyright (C) 2008 Axel Gembe\n"); 
    320430        printf("Copyright (C) 2009-2010 Daniel Dickinson\n"); 
    321  
    322         while ((c = getopt(argc, argv, "i:f:o:b:c:s:n:v:m:k:l:e:h:r:y:")) != -1) { 
    323                 switch (c) { 
    324                         case 'i': 
    325                                 kernel = optarg; 
    326                                 break; 
    327                         case 'f': 
    328                                 rootfs = optarg; 
    329                                 break; 
    330                         case 'o': 
    331                                 bin = optarg; 
    332                                 break; 
    333                         case 'b': 
    334                                 boardid = optarg; 
    335                                 break; 
    336                         case 'c': 
    337                                 chipid = optarg; 
    338                                 break; 
    339                         case 's': 
    340                                 flashstart = strtoul(optarg, NULL, 16); 
    341                                 break; 
    342                         case 'n': 
    343                                 fwoffset = strtoul(optarg, NULL, 16); 
    344                                 break; 
    345                         case 'v': 
    346                                 ver = optarg; 
    347                                 break; 
    348                         case 'm': 
    349                                 magic2 = optarg; 
    350                                 break; 
    351                         case 'k': 
    352                                 flash_bs = strtoul(optarg, NULL, 16); 
    353                                 break; 
    354                         case 'l': 
    355                                 loadaddr = strtoul(optarg, NULL, 16); 
    356                                 break; 
    357                         case 'e': 
    358                                 entry = strtoul(optarg, NULL, 16); 
    359                                 break; 
    360                         case 'r': 
    361                                 rsignature = optarg; 
    362                                 break; 
    363                         case 'y': 
    364                                 layoutver = optarg; 
    365                                 break; 
    366                         case 'h': 
    367                         default: 
    368                                 fprintf(stderr, "Usage: imagetag <parameters>\n\n"); 
    369                                 fprintf(stderr, "       -i <kernel>             - The LZMA compressed kernel file to include in the image\n"); 
    370                                 fprintf(stderr, "       -f <rootfs>             - The RootFS file to include in the image\n"); 
    371                                 fprintf(stderr, "       -o <bin>                - The output file\n"); 
    372                                 fprintf(stderr, "       -b <boardid>            - The board id to set in the image (i.e. \"96345GW2\")\n"); 
    373                                 fprintf(stderr, "       -c <chipid>             - The chip id to set in the image (i.e. \"6345\")\n"); 
    374                                 fprintf(stderr, "       -s <flashstart>         - Flash start address (i.e. \"0xBFC00000\"\n"); 
    375                                 fprintf(stderr, "       -n <fwoffset>           - \n"); 
    376                                 fprintf(stderr, "       -v <version>            - \n"); 
    377                                 fprintf(stderr, "       -m <magic2>             - \n"); 
    378                                 fprintf(stderr, "       -k <flash_bs>           - flash erase block size\n"); 
    379                                 fprintf(stderr, "       -l <loadaddr>           - Address where the kernel expects to be loaded (defaults to 0x80010000)\n"); 
    380                                 fprintf(stderr, "       -e <entry>              - Address where the kernel entry point will end up\n"); 
    381                                 fprintf(stderr, "       -r <signature>          - vendor specific signature, for those that need it"); 
    382                                 fprintf(stderr, "       -y <layoutver>          - Flash Layout Version (2.2x code versions need this)"); 
    383                                 fprintf(stderr, "       -h                      - Displays this text\n\n"); 
    384                                 return 1; 
    385                 } 
    386         } 
    387  
    388         if (!boardid || !chipid) { 
    389                 fprintf(stderr, "You need to specify the board (-b) and chip id (-c)!\n"); 
    390                 return 1; 
    391         } 
    392  
    393         if (entry == 0) { 
    394                 fprintf(stderr, "You need to specify the kernel entry (-e)\n"); 
    395                 return 1; 
    396         } 
    397  
    398         /* Fallback to defaults */ 
    399  
    400         fwaddr = flashstart + fwoffset; 
    401  
    402         if (!magic2) { 
    403                 magic2 = malloc(sizeof(char) * 14); 
    404                 if (!magic2) { 
    405                         perror("malloc"); 
    406                         return 1; 
    407                 } 
    408                 strcpy(magic2, IMAGETAG_MAGIC2); 
    409         } 
    410  
    411         if (!ver) { 
    412                 ver = malloc(sizeof(char) * 4); 
    413                 if (!ver) { 
    414                         perror("malloc"); 
    415                         return 1; 
    416                 } 
    417                 strcpy(ver, IMAGETAG_VER); 
    418         } 
    419  
    420  
    421         return tagfile(kernel, rootfs, bin, boardid, chipid, fwaddr, loadaddr, entry, ver, magic2, flash_bs, rsignature, layoutver); 
     431        printf("Licensed under the terms of the Gnu General Public License\n"); 
     432 
     433        kernel = parsed_args.kernel_arg; 
     434        rootfs = parsed_args.rootfs_arg; 
     435        bin = parsed_args.output_arg; 
     436        if (strlen(parsed_args.tag_version_arg) >= TAGVER_LEN) { 
     437          fprintf(stderr, "Error: Tag Version (tag_version,v) too long.\n"); 
     438          exit(1); 
     439        } 
     440        if (strlen(parsed_args.boardid_arg) >= BOARDID_LEN) { 
     441          fprintf(stderr, "Error: Board ID (boardid,b) too long.\n"); 
     442          exit(1); 
     443        } 
     444        if (strlen(parsed_args.chipid_arg) >= CHIPID_LEN) { 
     445          fprintf(stderr, "Error: Chip ID (chipid,c) too long.\n"); 
     446          exit(1); 
     447        } 
     448        if (strlen(parsed_args.signature_arg) >= SIG1_LEN) { 
     449          fprintf(stderr, "Error: Magic string (signature,a) too long.\n"); 
     450          exit(1); 
     451        } 
     452        if (strlen(parsed_args.signature2_arg) >= SIG2_LEN) { 
     453          fprintf(stderr, "Error: Second magic string (signature2,m) too long.\n"); 
     454          exit(1); 
     455        } 
     456        if (parsed_args.layoutver_given) { 
     457          if (strlen(parsed_args.layoutver_arg) > FLASHLAYOUTVER_LEN) { 
     458                fprintf(stderr, "Error: Flash layout version (layoutver,y) too long.\n"); 
     459                exit(1); 
     460          } 
     461        } 
     462        if (parsed_args.rsa_signature_given) { 
     463          if (strlen(parsed_args.rsa_signature_arg) > RSASIG_LEN) { 
     464                fprintf(stderr, "Error: RSA Signature (rsa_signature,r) too long.\n"); 
     465                exit(1); 
     466          } 
     467        } 
     468 
     469        if (parsed_args.info1_given) { 
     470          if (strlen(parsed_args.info1_arg) >= TAGINFO1_LEN) { 
     471                fprintf(stderr, "Error: Vendor Information 1 (info1) too long.\n"); 
     472                exit(1); 
     473          } 
     474        } 
     475 
     476        if (parsed_args.info2_given) { 
     477          if (strlen(parsed_args.info2_arg) >= TAGINFO2_LEN) { 
     478                fprintf(stderr, "Error: Vendor Information 2 (info2) too long.\n"); 
     479                exit(1); 
     480          } 
     481        } 
     482 
     483        if (parsed_args.altinfo_given) { 
     484          if (strlen(parsed_args.altinfo_arg) >= ALTTAGINFO_LEN) { 
     485                fprintf(stderr, "Error: Vendor Information 1 (info1) too long.\n"); 
     486                exit(1); 
     487          } 
     488        } 
     489        flash_start = strtoul(parsed_args.flash_start_arg, NULL, 16); 
     490        image_offset = strtoul(parsed_args.image_offset_arg, NULL, 16); 
     491        block_size = strtoul(parsed_args.block_size_arg, NULL, 16); 
     492 
     493        if (!parsed_args.kernel_file_has_header_flag) { 
     494          load_address = strtoul(parsed_args.load_addr_arg, NULL, 16); 
     495          entry = strtoul(parsed_args.entry_arg, NULL, 16); 
     496          if (load_address == 0) { 
     497                fprintf(stderr, "Error: Invalid value for load address\n"); 
     498          } 
     499          if (entry == 0) { 
     500                fprintf(stderr, "Error: Invalid value for entry\n"); 
     501          } 
     502        } 
     503         
     504        return tagfile(kernel, rootfs, bin, &parsed_args, flash_start, image_offset, block_size, load_address, entry); 
    422505} 
Note: See TracChangeset for help on using the changeset viewer.