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

Sources/firmware-utils/src/mkedimaximg.c

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  * Copyright (C) 2011 Vasilis Tsiligiannis <b_tsiligiannis@silverton.gr>
  4  */
  5 
  6 #include <stdio.h>
  7 #include <stdlib.h>
  8 #include <string.h>
  9 #include <byteswap.h>
 10 #include <libgen.h>
 11 #include <getopt.h>
 12 #include <errno.h>
 13 #include <sys/stat.h>
 14 #include <endian.h>     /* for __BYTE_ORDER */
 15 
 16 #define FALSE 0
 17 #define TRUE 1
 18 
 19 #if (__BYTE_ORDER == __LITTLE_ENDIAN)
 20 #  define HOST_TO_LE16(x)       (x)
 21 #  define HOST_TO_LE32(x)       (x)
 22 #  define HOST_TO_BE16(x)       bswap_16(x)
 23 #  define HOST_TO_BE32(x)       bswap_32(x)
 24 #else
 25 #  define HOST_TO_LE16(x)       bswap_16(x)
 26 #  define HOST_TO_LE32(x)       bswap_32(x)
 27 #  define HOST_TO_BE16(x)       (x)
 28 #  define HOST_TO_BE32(x)       (x)
 29 #endif
 30 
 31 struct header
 32 {
 33     unsigned char sign[4];
 34     unsigned int start;
 35     unsigned int flash;
 36     unsigned char model[4];
 37     unsigned int size;
 38 } __attribute__ ((packed));
 39 
 40 struct finfo
 41 {
 42     char *name;
 43     off_t size;
 44 };
 45 
 46 struct buf
 47 {
 48     char *start;
 49     size_t size;
 50 };
 51 
 52 static char *progname;
 53 static int force_be = FALSE;
 54 
 55 static void usage(int status)
 56 {
 57     FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout;
 58 
 59     fprintf(stream, "Usage: %s [OPTIONS...]\n", progname);
 60     fprintf(stream,
 61             "\n"
 62             "Options:\n"
 63             "  -s <sig>        set image signature to <sig>\n"
 64             "  -m <model>      set model to <model>\n"
 65             "  -i <file>       read input from file <file>\n"
 66             "  -o <file>       write output to file <file>\n"
 67             "  -f <flash>      set flash address to <flash>\n"
 68             "  -S <start>      set start address to <start>\n"
 69             "  -b              big-endianness mode\n");
 70 
 71     exit(status);
 72 }
 73 
 74 static int strtou32(char *arg, unsigned int *val)
 75 {
 76     char *endptr = NULL;
 77 
 78     errno = 0;
 79     *val = strtoul(arg, &endptr, 0);
 80     if (errno || (endptr == arg) || (*endptr && (endptr != NULL))) {
 81         return EXIT_SUCCESS;
 82     }
 83 
 84     return EXIT_FAILURE;
 85 }
 86 
 87 static unsigned short fwcsum (struct buf *buf) {
 88     int i;
 89     unsigned short ret = 0;
 90 
 91     for (i = 0; i < buf->size / 2; i++) {
 92         if (force_be == FALSE)
 93             ret -= ((unsigned short *) buf->start)[i];
 94         else
 95             ret -= HOST_TO_BE16(((unsigned short *) buf->start)[i]);
 96     }
 97     
 98     return ret;
 99 }
100 
101 static int fwread(struct finfo *finfo, struct buf *buf)
102 {
103     FILE *f;
104     
105     f = fopen(finfo->name, "r");
106     if (!f) {
107         fprintf(stderr, "could not open \"%s\" for reading\n", finfo->name);
108         usage(EXIT_FAILURE);
109     }
110 
111     buf->size = fread(buf->start, 1, finfo->size, f);
112     if (buf->size != finfo->size) {
113         fprintf(stderr, "unable to read from file \"%s\"\n", finfo->name);
114         usage(EXIT_FAILURE);
115     }
116 
117     fclose(f);
118 
119     return EXIT_SUCCESS;
120 }
121 
122 static int fwwrite(struct finfo *finfo, struct buf *buf)
123 {
124     FILE *f;
125 
126     f = fopen(finfo->name, "w");
127     if (!f) {
128         fprintf(stderr, "could not open \"%s\" for writing\n", finfo->name);
129         usage(EXIT_FAILURE);
130     }
131 
132     buf->size = fwrite(buf->start, 1, finfo->size, f);
133     if (buf->size != finfo->size) {
134         fprintf(stderr, "unable to write to file \"%s\"\n", finfo->name);
135         usage(EXIT_FAILURE);
136     }
137 
138     fclose(f);
139 
140     return EXIT_SUCCESS;
141 }       
142   
143 int main(int argc, char **argv)
144 {
145     struct stat st;
146     struct header header;
147     struct buf ibuf, obuf;
148     struct finfo ifinfo, ofinfo;
149     unsigned short csum;
150     int c;
151 
152     ifinfo.name = ofinfo.name = NULL;
153     header.flash = header.size = header.start = 0;
154     progname = basename(argv[0]);
155 
156     while((c = getopt(argc, argv, "i:o:m:s:f:S:h:b")) != -1) {
157         switch (c) {
158         case 'i':
159             ifinfo.name = optarg;
160             break;
161         case 'o':
162             ofinfo.name = optarg;
163             break;
164         case 'm':
165             if (strlen(optarg) != 4) {
166                 fprintf(stderr, "model must be 4 characters long\n");
167                 usage(EXIT_FAILURE);
168             }
169             memcpy(header.model, optarg, 4);
170             break;
171         case 's':
172             if (strlen(optarg) != 4) {
173                 fprintf(stderr, "signature must be 4 characters long\n");
174                 usage(EXIT_FAILURE);
175             }
176             memcpy(header.sign, optarg, 4);
177             break;
178         case 'h':
179             usage(EXIT_SUCCESS);
180             break;
181         case 'f':
182             if (!strtou32(optarg, &header.flash)) {
183                 fprintf(stderr, "invalid flash address specified\n");
184                 usage(EXIT_FAILURE);
185             }
186             break;
187         case 'S':
188             if (!strtou32(optarg, &header.start)) {
189                 fprintf(stderr, "invalid start address specified\n");
190                 usage(EXIT_FAILURE);
191             }
192             break;
193         case 'b':
194             force_be = TRUE;
195             break;
196         default:
197             usage(EXIT_FAILURE);
198             break;
199         }
200     }
201 
202     if (ifinfo.name == NULL) {
203         fprintf(stderr, "no input file specified\n");
204         usage(EXIT_FAILURE);
205     }
206 
207     if (ofinfo.name == NULL) {
208         fprintf(stderr, "no output file specified\n");
209         usage(EXIT_FAILURE);
210     }
211 
212     if (stat(ifinfo.name, &st)) {
213         fprintf(stderr, "stat failed on %s\n", ifinfo.name);
214         usage(EXIT_FAILURE);
215     }
216 
217     if (header.sign == NULL) {
218         fprintf(stderr, "no signature specified\n");
219         usage(EXIT_FAILURE);
220     }
221 
222     if (header.model == NULL) {
223         fprintf(stderr, "no model specified\n");
224         usage(EXIT_FAILURE);
225     }
226 
227     if (!header.flash) {
228         fprintf(stderr, "no flash address specified\n");
229         usage(EXIT_FAILURE);
230     }
231 
232     if (!header.start) {
233         fprintf(stderr, "no start address specified\n");
234         usage(EXIT_FAILURE);
235     }
236 
237     ifinfo.size = st.st_size;
238 
239     obuf.size = ifinfo.size + sizeof(struct header) + sizeof(unsigned short);
240     if (obuf.size % sizeof(unsigned short))
241         obuf.size++;
242 
243     obuf.start = malloc(obuf.size);
244     if (!obuf.start) {
245         fprintf(stderr, "no memory for buffer\n");
246         usage(EXIT_FAILURE);
247     }
248     memset(obuf.start, 0, obuf.size);
249 
250     ibuf.size = ifinfo.size;
251     ibuf.start = obuf.start + sizeof(struct header);
252     
253     if (fwread(&ifinfo, &ibuf))
254         usage(EXIT_FAILURE);
255 
256     if (force_be == FALSE) {
257         header.flash = HOST_TO_LE32(header.flash);
258         header.size = HOST_TO_LE32(obuf.size - sizeof(struct header));
259         header.start = HOST_TO_LE32(header.start);
260     } else {
261         header.flash = HOST_TO_BE32(header.flash);
262         header.size = HOST_TO_BE32(obuf.size - sizeof(struct header));
263         header.start = HOST_TO_BE32(header.start);
264     }
265 
266     memcpy (obuf.start, &header, sizeof(struct header));
267 
268     if (force_be == FALSE)
269         csum = HOST_TO_LE16(fwcsum(&ibuf));
270     else
271         csum = HOST_TO_BE16(fwcsum(&ibuf));
272 
273     memcpy(obuf.start + obuf.size - sizeof(unsigned short),
274            &csum, sizeof(unsigned short));
275 
276     ofinfo.size = obuf.size;
277 
278     if (fwwrite(&ofinfo, &obuf))
279         usage(EXIT_FAILURE);
280 
281     return EXIT_SUCCESS;
282 }
283 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt