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

Sources/firmware-utils/src/mkheader_gemtek.c

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  * Copyright (C) 2014  Claudio Leite <leitec@staticky.com>
  4  */
  5 
  6 /*
  7  * Builds a proper flash image for routers using some Gemtek
  8  * OEM boards. These include the Airlink101 AR725W, the
  9  * Asante SmartHub 600 (AWRT-600N), and Linksys WRT100/110.
 10  *
 11  * The resulting image is compatible with the factory firmware
 12  * web upgrade and TFTP interface.
 13  *
 14  * To build:
 15  *  gcc -O2 -o mkheader_gemtek mkheader_gemtek.c -lz
 16  *
 17  * Claudio Leite <leitec@staticky.com>
 18  */
 19 
 20 #include <stdio.h>
 21 #include <stdlib.h>
 22 #include <stdint.h>
 23 #include <string.h>
 24 
 25 #include <zlib.h>               /* for crc32() */
 26 
 27 /*
 28  * The header is in little-endian format. In case
 29  * we are on a BE host, we need to swap binary
 30  * values.
 31  */
 32 #ifdef __APPLE__
 33 # include <libkern/OSByteOrder.h>
 34 # define le32 OSSwapHostToLittleInt32
 35 #else
 36 # if defined(__linux__)
 37 #  include <endian.h>
 38 #  if __BYTE_ORDER == __BIG_ENDIAN
 39 #   define CPU_BIG_ENDIAN
 40 #  endif
 41 # else
 42 #  include <sys/endian.h>               /* BSD's should have this */
 43 #  if _BYTE_ORDER == _BIG_ENDIAN
 44 #   define CPU_BIG_ENDIAN
 45 #  endif
 46 # endif
 47 # ifdef CPU_BIG_ENDIAN
 48 #  define le32(x) (((x & 0xff000000) >> 24) | \
 49                    ((x & 0x00ff0000) >> 8)  | \
 50                    ((x & 0x0000ff00) << 8)  | \
 51                    ((x & 0x000000ff) << 24))
 52 # else
 53 #  define le32(x) (x)
 54 # endif
 55 #endif
 56 
 57 struct gemtek_header {
 58         uint8_t         magic[4];
 59         uint8_t         version[4];
 60         uint32_t        product_id;
 61         uint32_t        imagesz;
 62         uint32_t        checksum;
 63         uint32_t        fast_checksum;
 64         uint8_t         build[4];
 65         uint8_t         lang[4];
 66 };
 67 
 68 #define HDRLEN  sizeof(struct gemtek_header)
 69 
 70 struct machines {
 71         char           *desc;
 72         char           *id;
 73         uint32_t        maxsize;
 74         struct gemtek_header header;
 75 };
 76 
 77 struct machines mach_def[] = {
 78         {"Airlink101 AR725W", "ar725w", 0x340000,
 79                 {"GMTK", "1003", le32(0x03000001), 0, 0,
 80                   0, "01\0\0", "EN\0\0"}},
 81         {"Asante AWRT-600N", "awrt600n", 0x340000,
 82                 {"A600", "1005", le32(0x03000001), 0, 0,
 83                   0, "01\0\0", "EN\0\0"}},
 84         {"Linksys WRT100", "wrt100", 0x320000,
 85                 {"GMTK", "1007", le32(0x03040001), 0, 0,
 86                   0, "2\0\0\0", "EN\0\0"}},
 87         {"Linksys WRT110", "wrt110", 0x320000,
 88                 {"GMTK", "1007", le32(0x03040001), 0, 0,
 89                   0, "2\0\0\0", "EN\0\0"}},
 90         {0}
 91 };
 92 
 93 int
 94 main(int argc, char *argv[])
 95 {
 96         unsigned long   res, flen;
 97         struct gemtek_header my_hdr;
 98         FILE           *f, *f_out;
 99         int             image_type = -1, index;
100         uint8_t        *buf;
101         uint32_t        crc;
102 
103         if (argc < 3) {
104                 fprintf(stderr, "mkheader_gemtek <uImage> <webflash image> [machine ID]\n");
105                 fprintf(stderr, "  where [machine ID] is one of:\n");
106                 for (index = 0; mach_def[index].desc != 0; index++) {
107                         fprintf(stderr, "    %-10s  %s", mach_def[index].id, mach_def[index].desc);
108                         if (index == 0)
109                                 fprintf(stderr, " (default)\n");
110                         else
111                                 fprintf(stderr, "\n");
112                 }
113 
114                 exit(-1);
115         }
116 
117         if (argc == 4) {
118                 for(index = 0; mach_def[index].id != 0; index++) {
119                         if(strcmp(mach_def[index].id, argv[3]) == 0) {
120                                 image_type = index;
121                                 break;
122                         }
123                 }
124 
125                 if(image_type == -1) {
126                         fprintf(stderr, "\nERROR: invalid machine type\n");
127                         exit(-1);
128                 }
129         } else
130                 image_type = 0;
131 
132         printf("Opening %s...\n", argv[1]);
133 
134         f = fopen(argv[1], "r");
135         if(!f) {
136                 fprintf(stderr, "\nERROR: couldn't open input image\n");
137                 exit(-1);
138         }
139 
140         fseek(f, 0, SEEK_END);
141         flen = (unsigned long) ftell(f);
142 
143         printf("  %lu (0x%lX) bytes long\n", flen, flen);
144 
145         if (flen > mach_def[image_type].maxsize) {
146                 fprintf(stderr, "\nERROR: image exceeds maximum compatible size\n");
147                 goto f_error;
148         }
149 
150         buf = malloc(flen + HDRLEN);
151         if (!buf) {
152                 fprintf(stderr, "\nERROR: couldn't allocate buffer\n");
153                 goto f_error;
154         }
155         rewind(f);
156         res = fread(buf + HDRLEN, 1, flen, f);
157         if (res != flen) {
158                 perror("Couldn't read entire file: fread()");
159                 goto f_error;
160         }
161         fclose(f);
162 
163         printf("\nCreating %s...\n", argv[2]);
164 
165         memcpy(&my_hdr, &mach_def[image_type].header, HDRLEN);
166 
167         printf("  Using %s magic\n", mach_def[image_type].desc);
168 
169         my_hdr.imagesz = le32(flen + HDRLEN);
170         memcpy(my_hdr.lang, "EN", 2);
171 
172         memcpy(buf, &my_hdr, HDRLEN);
173 
174         crc = crc32(0, buf, flen + HDRLEN);
175         printf("  CRC32: %08X\n", crc);
176 
177         my_hdr.checksum = le32(crc);
178         memcpy(buf, &my_hdr, HDRLEN);
179 
180         printf("  Writing...\n");
181 
182         f_out = fopen(argv[2], "w");
183         if(!f_out) {
184                 fprintf(stderr, "\nERROR: couldn't open output image\n");
185                 exit(-1);
186         }
187 
188         fwrite(buf, 1, flen + HDRLEN, f_out);
189 
190         fclose(f_out);
191 
192         free(buf);
193         return 0;
194 
195 f_error:
196         fclose(f);
197         exit(-1);
198 }
199 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt