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

4.104.114.84.95
Last change on this file since 3239698 was 3239698, checked in by Ralf Corsepius <ralf.corsepius@…>, on 04/15/04 at 13:26:21

Remove stray white spaces.

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