• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/firmware-utils/src/zyxbcm.c

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  * zyxbcm.c - based on Jonas Gorski's spw303v.c
  4  *
  5  * Copyright (C) 2014 Álvaro Fernández Rojas <noltari@gmail.com>
  6  */
  7 
  8 #include <arpa/inet.h>
  9 #include <stdio.h>
 10 #include <stdlib.h>
 11 #include <string.h>
 12 #include <stdint.h>
 13 #include <unistd.h>
 14 #include <sys/stat.h>
 15 
 16 #define TAGVER_LEN 4                    /* Length of Tag Version */
 17 #define SIG1_LEN 20                     /* Company Signature 1 Length */
 18 #define SIG2_LEN 14                     /* Company Signature 2 Lenght */
 19 #define BOARDID_LEN 16                  /* Length of BoardId */
 20 #define ENDIANFLAG_LEN 2                /* Endian Flag Length */
 21 #define CHIPID_LEN 6                    /* Chip Id Length */
 22 #define IMAGE_LEN 10                    /* Length of Length Field */
 23 #define ADDRESS_LEN 12                  /* Length of Address field */
 24 #define DUALFLAG_LEN 2                  /* Dual Image flag Length */
 25 #define INACTIVEFLAG_LEN 2              /* Inactie Flag Length */
 26 #define RSASIG_LEN 20                   /* Length of RSA Signature in tag */
 27 #define TAGINFO1_LEN 30                 /* Length of vendor information field1 in tag */
 28 #define ZYX_TAGINFO1_LEN 20             /* Length of vendor information field1 in tag */
 29 #define FLASHLAYOUTVER_LEN 4            /* Length of Flash Layout Version String tag */
 30 #define TAGINFO2_LEN 16                 /* Length of vendor information field2 in tag */
 31 #define CRC_LEN 4                       /* Length of CRC in bytes */
 32 
 33 #define IMAGETAG_CRC_START 0xFFFFFFFF
 34 
 35 struct bcm_tag {
 36         char tagVersion[TAGVER_LEN];                    // 0-3: Version of the image tag
 37         char sig_1[SIG1_LEN];                           // 4-23: Company Line 1
 38         char sig_2[SIG2_LEN];                           // 24-37: Company Line 2
 39         char chipid[CHIPID_LEN];                        // 38-43: Chip this image is for
 40         char boardid[BOARDID_LEN];                      // 44-59: Board name
 41         char big_endian[ENDIANFLAG_LEN];                // 60-61: Map endianness -- 1 BE 0 LE
 42         char totalLength[IMAGE_LEN];                    // 62-71: Total length of image
 43         char cfeAddress[ADDRESS_LEN];                   // 72-83: Address in memory of CFE
 44         char cfeLength[IMAGE_LEN];                      // 84-93: Size of CFE
 45         char flashImageStart[ADDRESS_LEN];              // 94-105: Address in memory of image start (kernel for OpenWRT, rootfs for stock firmware)
 46         char flashRootLength[IMAGE_LEN];                // 106-115: Size of rootfs for flashing
 47         char kernelAddress[ADDRESS_LEN];                // 116-127: Address in memory of kernel
 48         char kernelLength[IMAGE_LEN];                   // 128-137: Size of kernel
 49         char dualImage[DUALFLAG_LEN];                   // 138-139: Unused at present
 50         char inactiveFlag[INACTIVEFLAG_LEN];            // 140-141: Unused at present
 51         char rsa_signature[RSASIG_LEN];                 // 142-161: RSA Signature (unused at present; some vendors may use this)
 52         char information1[TAGINFO1_LEN];                // 162-191: Compilation and related information (not generated/used by OpenWRT)
 53         char flashLayoutVer[FLASHLAYOUTVER_LEN];        // 192-195: Version flash layout
 54         char fskernelCRC[CRC_LEN];                      // 196-199: kernel+rootfs CRC32
 55         char information2[TAGINFO2_LEN];                // 200-215: Unused at present except Alice Gate where is is information
 56         char imageCRC[CRC_LEN];                         // 216-219: CRC32 of image less imagetag (kernel for Alice Gate)
 57         char rootfsCRC[CRC_LEN];                        // 220-223: CRC32 of rootfs partition
 58         char kernelCRC[CRC_LEN];                        // 224-227: CRC32 of kernel partition
 59         char imageSequence[4];                          // 228-231: Image sequence number
 60         char rootLength[4];                             // 232-235: steal from reserved1 to keep the real root length so we can use in the flash map even after we have change the rootLength to 0 to satisfy devices that check CRC on every boot
 61         char headerCRC[CRC_LEN];                        // 236-239: CRC32 of header excluding tagVersion
 62         char reserved2[16];                             // 240-255: Unused at present
 63 };
 64 
 65 struct zyxbcm_tag {
 66         char tagVersion[TAGVER_LEN];                    // 0-3: Version of the image tag
 67         char sig_1[SIG1_LEN];                           // 4-23: Company Line 1
 68         char sig_2[SIG2_LEN];                           // 24-37: Company Line 2
 69         char chipid[CHIPID_LEN];                        // 38-43: Chip this image is for
 70         char boardid[BOARDID_LEN];                      // 44-59: Board name
 71         char big_endian[ENDIANFLAG_LEN];                // 60-61: Map endianness -- 1 BE 0 LE
 72         char totalLength[IMAGE_LEN];                    // 62-71: Total length of image
 73         char cfeAddress[ADDRESS_LEN];                   // 72-83: Address in memory of CFE
 74         char cfeLength[IMAGE_LEN];                      // 84-93: Size of CFE
 75         char flashImageStart[ADDRESS_LEN];              // 94-105: Address in memory of image start (kernel for OpenWRT, rootfs for stock firmware)
 76         char flashRootLength[IMAGE_LEN];                // 106-115: Size of rootfs for flashing
 77         char kernelAddress[ADDRESS_LEN];                // 116-127: Address in memory of kernel
 78         char kernelLength[IMAGE_LEN];                   // 128-137: Size of kernel
 79         char dualImage[DUALFLAG_LEN];                   // 138-139: Unused at present
 80         char inactiveFlag[INACTIVEFLAG_LEN];            // 140-141: Unused at present
 81         char rsa_signature[RSASIG_LEN];                 // 142-161: RSA Signature (unused at present; some vendors may use this)
 82         char information1[ZYX_TAGINFO1_LEN];            // 162-181: Compilation and related information (not generated/used by OpenWRT)
 83         char flashImageEnd[ADDRESS_LEN];                // 182-193: Address in memory of image end
 84         char fskernelCRC[CRC_LEN];                      // 194-197: kernel+rootfs CRC32
 85         char reserved1[2];                              // 198-199: Unused at present
 86         char information2[TAGINFO2_LEN];                // 200-215: Unused at present except Alice Gate where is is information
 87         char imageCRC[CRC_LEN];                         // 216-219: CRC32 of image less imagetag (kernel for Alice Gate)
 88         char rootfsCRC[CRC_LEN];                        // 220-223: CRC32 of rootfs partition
 89         char kernelCRC[CRC_LEN];                        // 224-227: CRC32 of kernel partition
 90         char imageSequence[4];                          // 228-231: Image sequence number
 91         char rootLength[4];                             // 232-235: steal from reserved1 to keep the real root length so we can use in the flash map even after we have change the rootLength to 0 to satisfy devices that check CRC on every boot
 92         char headerCRC[CRC_LEN];                        // 236-239: CRC32 of header excluding tagVersion
 93         char reserved2[16];                             // 240-255: Unused at present
 94 };
 95 
 96 static uint32_t crc32tab[256] = {
 97         0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
 98         0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
 99         0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
100         0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
101         0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
102         0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
103         0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
104         0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
105         0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
106         0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
107         0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
108         0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
109         0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
110         0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
111         0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
112         0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
113         0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
114         0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
115         0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
116         0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
117         0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
118         0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
119         0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
120         0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
121         0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
122         0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
123         0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
124         0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
125         0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
126         0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
127         0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
128         0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
129 };
130 
131 uint32_t crc32(uint32_t crc, uint8_t *data, size_t len)
132 {
133         while (len--)
134                 crc = (crc >> 8) ^ crc32tab[(crc ^ *data++) & 0xFF];
135 
136         return crc;
137 }
138 
139 void fix_header(void *buf)
140 {
141         struct bcm_tag *bcmtag = buf;
142         struct zyxbcm_tag *zyxtag = buf;
143         uint8_t fskernel_crc[CRC_LEN];
144         uint32_t crc;
145         uint64_t flash_start, rootfs_len, kernel_len;
146 
147         /* Backup values */
148         flash_start = strtoul(bcmtag->flashImageStart, NULL, 10);
149         rootfs_len = strtoul(bcmtag->flashRootLength, NULL, 10);
150         kernel_len = strtoul(bcmtag->kernelLength, NULL, 10);
151         memcpy(fskernel_crc, bcmtag->fskernelCRC, CRC_LEN);
152 
153         /* Clear values */
154         zyxtag->information1[ZYX_TAGINFO1_LEN - 1] = 0;
155         memset(zyxtag->flashImageEnd, 0, ADDRESS_LEN);
156         memset(zyxtag->fskernelCRC, 0, CRC_LEN);
157         memset(zyxtag->reserved1, 0, 2);
158 
159         /* Replace values */
160         sprintf(zyxtag->flashImageEnd, "%lu", flash_start + rootfs_len + kernel_len);
161         memcpy(zyxtag->fskernelCRC, fskernel_crc, CRC_LEN);
162 
163         /* Update tag crc */
164         crc = htonl(crc32(IMAGETAG_CRC_START, buf, 236));
165         memcpy(zyxtag->headerCRC, &crc, 4);
166 }
167 
168 void usage(void) __attribute__ (( __noreturn__ ));
169 
170 void usage(void)
171 {
172         fprintf(stderr, "Usage: zyxbcm [-i <inputfile>] [-o <outputfile>]\n");
173         exit(EXIT_FAILURE);
174 }
175 
176 int main(int argc, char **argv)
177 {
178         char buf[1024]; /* keep this at 1k or adjust garbage calc below */
179         FILE *in = stdin, *out = stdout;
180         char *ifn = NULL, *ofn = NULL;
181         size_t n;
182         int c, first_block = 1;
183 
184         while ((c = getopt(argc, argv, "i:o:h")) != -1) {
185                 switch (c) {
186                         case 'i':
187                                 ifn = optarg;
188                                 break;
189                         case 'o':
190                                 ofn = optarg;
191                                 break;
192                         case 'h':
193                         default:
194                                 usage();
195                 }
196         }
197 
198         if (optind != argc || optind == 1) {
199                 fprintf(stderr, "illegal arg \"%s\"\n", argv[optind]);
200                 usage();
201         }
202 
203         if (ifn && !(in = fopen(ifn, "r"))) {
204                 fprintf(stderr, "can not open \"%s\" for reading\n", ifn);
205                 usage();
206         }
207 
208         if (ofn && !(out = fopen(ofn, "w"))) {
209                 fprintf(stderr, "can not open \"%s\" for writing\n", ofn);
210                 usage();
211         }
212 
213         while ((n = fread(buf, 1, sizeof(buf), in)) > 0) {
214                 if (n < sizeof(buf)) {
215                         if (ferror(in)) {
216                         FREAD_ERROR:
217                                 fprintf(stderr, "fread error\n");
218                                 return EXIT_FAILURE;
219                         }
220                 }
221 
222                 if (first_block && n >= 256) {
223                         fix_header(buf);
224                         first_block = 0;
225                 }
226 
227                 if (!fwrite(buf, n, 1, out)) {
228                 FWRITE_ERROR:
229                         fprintf(stderr, "fwrite error\n");
230                         return EXIT_FAILURE;
231                 }
232         }
233 
234         if (ferror(in)) {
235                 goto FREAD_ERROR;
236         }
237 
238         if (fflush(out)) {
239                 goto FWRITE_ERROR;
240         }
241 
242         fclose(in);
243         fclose(out);
244 
245         return EXIT_SUCCESS;
246 }
247 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt