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