source: rtems/c/src/lib/libbsp/i386/pc386/tools/bin2boot.c @ 441b90e

4.115
Last change on this file since 441b90e was 1792c7a, checked in by Ralf Corsepius <ralf.corsepius@…>, on Feb 10, 2009 at 10:27:37 AM

2009-02-10 Ralf Corsépius <ralf.corsepius@…>

  • bin2boot.c: Use stdint/inttypes to workaround build warnings on 64bit hosts.
  • Property mode set to 100644
File size: 8.5 KB
Line 
1
2/*
3 * Simplyfied version of original bin2boot
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <stdint.h>
9#include <inttypes.h>
10#include <unistd.h>
11#include <string.h>
12
13static unsigned char buf[512];
14
15static void usage(void)
16{
17  printf("usage: bin2boot [-h][-v] <outFile> <headerAddr> \n");
18  printf("<imFile1> <imAddr1> <imSize1> [<imFile2> <imAddr2> <imSize2>]\n");
19  printf("this function makes image bootable by netboot\n");
20  printf("from one or two binary images\n");
21  printf("-h         - prints this message\n");
22  printf("-v         - verbose output\n");
23  printf("outFile    - output file\n");
24  printf("headerAddr - address to place header in memory\n");
25  printf("             it should be below or equal 0x97e00\n");
26  printf("imFile1    - first image\n");
27  printf("imAddr1    - its start address, image has to be placed whole\n");
28  printf("             below 0x98000 and should not overlap with header\n");
29  printf("imSize1    - actual size of compressed image, 0 for uncompressed\n");
30  printf("imFile2    - second image\n");
31  printf("imAddr2    - its start address\n");
32  printf("imSize2    - actual size of compressed image, 0 for uncompressed\n");
33
34  return;
35}
36
37int main(int argc, char* argv[])
38{
39  int      c, verbose;
40  extern   int optind;
41  FILE     *ofp, *ifp;
42  uintptr_t headerAddr, addr1, addr2;
43  int      size1, size2, len1, len2, len, imageCnt, cnt;
44  char     *ofile, *ifile, *end;
45
46  len2 = 0;   /* avoid warning */
47  size2 = 0;  /* avoid warning */
48  addr2 = 0;  /* avoid warning */
49  verbose = 0;
50
51  /* parse command line options */
52  while ((c = getopt(argc, argv, "hv")) >= 0)
53    {
54      switch (c)
55        {
56        case 'v':
57          verbose = 1;
58          break;
59        case 'h':
60          usage();
61          return 0;
62        default:
63          usage();
64          return 1;
65        }
66    }
67
68  if((argc - optind) != 8 && (argc - optind) != 5)
69    {
70      usage();
71      return 1;
72    }
73
74  ofile = argv[optind];
75  ofp   = fopen(ofile, "wb");
76  if(ofp == NULL)
77    {
78      fprintf(stderr, "unable to open file %s\n", ofile);
79      return 1;
80    }
81
82  /*
83   * Layout is very simple first 512 is header shared by all
84   * images, then images at 512 bytes border
85   */
86
87  /* Fill buffer with 0's */
88  memset(buf, 0, sizeof(buf));
89
90  fwrite(buf, 1, sizeof(buf), ofp);
91
92  optind++;
93  headerAddr = strtoul(argv[optind], &end, 0);
94  if(end == argv[optind])
95    {
96      fprintf(stderr, "bad headerAddr %s\n", argv[optind]);
97      fclose(ofp);
98      return 1;
99    }
100
101  if(headerAddr > 0x97e00)
102    {
103      fprintf(stderr, "headerAddr is too high 0x%08lx\n", headerAddr);
104      fclose(ofp);
105      return 1;
106    }
107
108  /* Copy the first image */
109  optind++;
110  ifile = argv[optind];
111  ifp   = fopen(ifile,"rb");
112  if(ifp == NULL)
113    {
114      fprintf(stderr, "unable to open output file %s\n", ifile);
115      fclose(ofp);
116      return 1;
117    }
118
119  optind++;
120  addr1 = strtoul(argv[optind], &end, 0);
121  if(end == argv[optind])
122    {
123      fprintf(stderr, "bad image address %s\n", argv[optind]);
124      fclose(ofp);
125      return 1;
126    }
127
128  optind++;
129  size1 = strtoul(argv[optind], &end, 0);
130  if(end == argv[optind])
131    {
132      fprintf(stderr, "bad image size %s\n", argv[optind]);
133      fclose(ofp);
134      return 1;
135    }
136
137  /* Copy first image out and remember its length */
138  cnt  = 0;
139  for(;;)
140    {
141      len = fread(buf, 1, sizeof(buf), ifp);
142
143      if(len != 0)
144        {
145          fwrite(buf, 1, len, ofp);
146          cnt += sizeof(buf);
147
148          if(len != sizeof(buf))
149            {
150              memset(buf, 0, sizeof(buf) - len);
151              fwrite(buf, 1, sizeof(buf) - len, ofp);
152              break;
153            }
154
155        }
156      else
157        {
158          break;
159        }
160    }
161
162  fclose(ifp);
163
164  len1 = cnt;
165
166  if(size1 == 0)
167    {
168      size1 = cnt;
169    }
170  else
171    {
172      memset(buf, 0, sizeof(buf));
173
174      while(cnt < size1)
175        {
176          fwrite(buf, 1, sizeof(buf), ofp);
177          cnt += sizeof(buf);
178        }
179
180      size1 = cnt;
181    }
182
183  /* Let us check agains overlapping */
184  if(!(addr1 >= (headerAddr + sizeof(buf)) || (headerAddr >= addr1+size1)))
185    {
186      /* Areas overlapped */
187      printf("area overlapping: \n");
188      printf("header address      0x%08lx, its memory size 0x%08zx\n",
189             headerAddr, sizeof(buf));
190      printf("first image address 0x%08lx, its memory size 0x%08x\n",
191             addr1, size1);
192
193      fclose(ofp);
194      return 1;
195    }
196
197  if((addr1 + size1) > 0x98000)
198    {
199      fprintf(stderr, "imAddr1 is too high 0x%08lx\n", addr1);
200      fclose(ofp);
201      return 1;
202    }
203
204  if(optind == (argc - 1))
205    {
206      imageCnt = 1;
207      goto writeHeader;
208    }
209
210  imageCnt = 2;
211
212  /* Copy Second Image */
213  optind++;
214  ifile = argv[optind];
215  ifp   = fopen(ifile,"rb");
216  if(ifp == NULL)
217    {
218      fprintf(stderr, "unable to open output file %s\n", ifile);
219      fclose(ofp);
220      return 1;
221    }
222
223  optind++;
224  addr2 = strtoul(argv[optind], &end, 0);
225  if(end == argv[optind])
226    {
227      fprintf(stderr, "bad image address %s\n", argv[optind]);
228      fclose(ofp);
229      return 1;
230    }
231
232  optind++;
233  size2 = strtoul(argv[optind], &end, 0);
234  if(end == argv[optind])
235    {
236      fprintf(stderr, "bad image size %s\n", argv[optind]);
237      fclose(ofp);
238      return 1;
239    }
240
241  /* Copy second image out and remember its length */
242  cnt  = 0;
243  for(;;)
244    {
245      len = fread(buf, 1, sizeof(buf), ifp);
246
247      if(len != 0)
248        {
249          fwrite(buf, len, 1, ofp);
250          cnt  += sizeof(buf);
251
252          if(len != sizeof(buf))
253            {
254              memset(buf, 0, sizeof(buf) - len);
255              fwrite(buf, 1, sizeof(buf) - len, ofp);
256              break;
257            }
258        }
259      else
260        {
261          break;
262        }
263    }
264
265  fclose(ifp);
266
267  len2 = cnt;
268
269  if(size2 == 0)
270    {
271      size2 = cnt;
272    }
273  else
274    {
275      memset(buf, 0, sizeof(buf));
276
277      while(cnt < size2)
278        {
279          fwrite(buf, 1, sizeof(buf), ofp);
280          cnt += sizeof(buf);
281        }
282
283      size2 = cnt;
284    }
285
286  /* Let us check against overlapping */
287  if(!((addr2 >= (addr1 + size1) && addr2 >= (headerAddr + sizeof(buf))) ||
288       (addr2 < addr1 && addr2 < headerAddr) ||
289       (addr1 > headerAddr && addr2 > (headerAddr + sizeof(buf)) &&
290        (addr2 + size2) <= addr1) ||
291       (addr1 < headerAddr && addr2 > (addr1 + size1) &&
292        (addr2 + size2) <= headerAddr)))
293
294    {
295      /* Areas overlapped */
296      printf("area overlapping: \n");
297      printf("header address       0x%08" PRIxPTR ", its memory size 0x%08zx\n",
298             headerAddr, sizeof(buf));
299      printf("first  image address 0x%08" PRIxPTR ", its memory size 0x%08x\n",
300             addr1, size1);
301      printf("second image address 0x%08" PRIxPTR ", its memory size 0x%08x\n",
302             addr2, size2);
303
304      fclose(ofp);
305      return 1;
306    }
307
308writeHeader:
309
310  /* We know everything so it is time to write buffer */
311  memset(buf, 0, 0x30);
312
313  buf[0x0]  = 0x36;
314  buf[0x1]  = 0x13;
315  buf[0x2]  = 0x03;
316  buf[0x3]  = 0x1b;
317
318  buf[0x4]  = 4;
319
320  /* Header address in ds:bx format */
321  buf[0x8]  = headerAddr & 0xf;
322  buf[0x9]  = 0;
323  buf[0xa]  = (headerAddr >> 4) & 0xff;
324  buf[0xb]  = (headerAddr >> 12) & 0xff;
325
326  /*
327   * Execute address in cs:ip format, which addr1
328   */
329  buf[0xc] = addr1 & 0xf;
330  buf[0xd] = 0;
331  buf[0xe] = (addr1 >> 4) & 0xff;
332  buf[0xf] = (addr1 >> 12) & 0xff;
333
334  /* Flags, tags and lengths */
335  buf[0x10] = 4;
336
337  if(imageCnt == 1)
338    {
339      buf[0x13] = 4;
340    }
341
342  /* Load address */
343  buf[0x14] = addr1 & 0xff;
344  buf[0x15] = (addr1 >> 8) & 0xff;
345  buf[0x16] = (addr1 >> 16) & 0xff;
346  buf[0x17] = (addr1 >> 24) & 0xff;
347
348  /* Image Length */
349  buf[0x18] = len1 & 0xff;
350  buf[0x19] = (len1 >> 8) & 0xff;
351  buf[0x1a] = (len1 >> 16) & 0xff;
352  buf[0x1b] = (len1 >> 24) & 0xff;
353
354  /* Memory Size */
355  buf[0x1c] = size1 & 0xff;
356  buf[0x1d] = (size1 >> 8) & 0xff;
357  buf[0x1e] = (size1 >> 16) & 0xff;
358  buf[0x1f] = (size1 >> 24) & 0xff;
359
360  if(imageCnt != 1)
361    {
362
363      /* Flags, tags and lengths */
364      buf[0x20] = 4;
365
366      buf[0x23] = 4;
367
368      /* Load address */
369      buf[0x24] = addr2 & 0xff;
370      buf[0x25] = (addr2 >> 8) & 0xff;
371      buf[0x26] = (addr2 >> 16) & 0xff;
372      buf[0x27] = (addr2 >> 24) & 0xff;
373
374      /* Image Length */
375      buf[0x28] = len2 & 0xff;
376      buf[0x29] = (len2 >> 8) & 0xff;
377      buf[0x2a] = (len2 >> 16) & 0xff;
378      buf[0x2b] = (len2 >> 24) & 0xff;
379
380      /* Memory Size */
381      buf[0x2c] = size2 & 0xff;
382      buf[0x2d] = (size2 >> 8) & 0xff;
383      buf[0x2e] = (size2 >> 16) & 0xff;
384      buf[0x2f] = (size2 >> 24) & 0xff;
385    }
386
387  rewind(ofp);
388
389  fwrite(buf, 1, 0x30, ofp);
390
391  fclose(ofp);
392
393  if(verbose)
394    {
395      printf("header address       0x%08" PRIxPTR ", its memory size 0x%08zx\n",
396             headerAddr, sizeof(buf));
397      printf("first  image address 0x%08" PRIxPTR ", its memory size 0x%08x\n",
398             addr1, size1);
399      printf("second image address 0x%08" PRIxPTR ", its memory size 0x%08x\n",
400             addr2, size2);
401    }
402
403  return 0;
404}
Note: See TracBrowser for help on using the repository browser.