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

4.104.114.84.95
Last change on this file since d2632274 was 7150f00f, checked in by Joel Sherrill <joel.sherrill@…>, on 12/01/97 at 22:06:48

Inclusion of PC386 BSP submitted by Pedro Miguel Da Cruz Neto Romano
<pmcnr@…> and Jose Rufino <ruf@…>
of NavIST (http://pandora.ist.utl.pt/).

  • Property mode set to 100644
File size: 8.1 KB
Line 
1/*-------------------------------------------------------------------------+
2| bin2boot.c v1.1 - PC386 BSP - 1997/08/18
3+--------------------------------------------------------------------------+
4| This file contains the i386 binary to boot image filter.
5+--------------------------------------------------------------------------+
6| (C) Copyright 1997 -
7| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
8|
9| http://pandora.ist.utl.pt
10|
11| Instituto Superior Tecnico * Lisboa * PORTUGAL
12+--------------------------------------------------------------------------+
13| Disclaimer:
14|
15| This file is provided "AS IS" without warranty of any kind, either
16| expressed or implied.
17+--------------------------------------------------------------------------*/
18
19
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23#include <unistd.h>
24#include "bytetype.h"
25#include "bootimg.h"
26
27/*-------------------------------------------------------------------------+
28| Constants
29+--------------------------------------------------------------------------*/
30#define SEG_MASK            0xffff0000
31                                /* Mask for segment part of seg:off address. */
32#define OFF_MASK            0x0000ffff
33                                 /* Mask for offset part of seg:off address. */
34#define DEFAULT_START_ADDR  0x10200     /* Default start address for binary. */
35#define BOOTIMG_HDR_SIZE    0x0200      /* Size of output file header.       */
36#define BUFFER_BLOCK_SIZE   0x1000      /* Size of transfer buffer size.     */
37#define LAST_BLOCK_SIZE     0x0200
38                 /* The output file must have a size multiple of this value. */
39
40
41/*-------------------------------------------------------------------------+
42| Macros
43+--------------------------------------------------------------------------*/
44#define getSeg(x) (Word)((x) >> 16)
45                    /* Return seg part (Word) of a seg:off address (DWord). */
46
47#define getOff(x) (Word)((x) & OFF_MASK)
48                    /* Return off part (Word) of a seg:off address (DWord). */
49
50#define getSegOff(x) ((((x) & SEG_MASK) << 12) + ((x) & OFF_MASK))
51                           /* Converts a flat address to a seg:off address. */
52
53/*-------------------------------------------------------------------------+
54| Global Variables
55+--------------------------------------------------------------------------*/
56const char UsageMsg[] = "\
57Usage: bin2boot [<infile> [<outfile>]] [-s <start_address>] [-v]\n\
58\n\
59    <infile>     : input file name\n\
60    <outfile>    : output file name\n\
61    -s <outfile> : start address of binary image\n\
62    -m <size>    : actual size (for compressed images)\n\
63    -v           : verbose output\n";                     /* Usage message. */
64
65
66/*-------------------------------------------------------------------------+
67| External Prototypes (for use with getopt)
68+--------------------------------------------------------------------------*/
69extern char *optarg;
70
71int getopt(int, char *const[], const char *);
72
73
74/*-------------------------------------------------------------------------+
75| Auxiliary Functions
76+--------------------------------------------------------------------------*/
77static DWord
78getNumArg(char *arg)
79{
80  char *dummy;
81
82  if (arg[0] == '0')
83    if ((arg[1] == 'x') || (arg[1] == 'X'))  /* Hexadecimal */
84      return (DWord)strtol(arg, &dummy, 16);
85    else  /* Octal */
86      return (DWord)strtol(arg, &dummy, 8);
87    else  /* Decimal */
88      return (DWord)strtol(arg, &dummy, 10);
89} /* getNumArg */
90
91
92/*-------------------------------------------------------------------------+
93| Main
94+--------------------------------------------------------------------------*/
95void main(int argc, char *argv[])
96{
97  FileHeader  bootimgFileHdr;             /* Output file header.             */
98  LoadingInfo imageInfo;                  /* Section header.                 */
99  Byte        auxBuf[BUFFER_BLOCK_SIZE];  /* */
100  DWord       nRead;                      /* Number of bytes read.           */
101  Word        padSize;                    /* Size of padding at end of file. */
102
103  char *progName = argv[0];               /* Program name for errors.        */ 
104  FILE *fpIn     = stdin;
105  FILE *fpOut    = stdout;
106  DWord binStart = DEFAULT_START_ADDR;    /* Start address of image.         */
107  DWord memLen   = 0;                  /* Real length for compressed images. */
108
109  char currArg;
110  int  argCount;
111  int  flag;          /* general purpose flag    */
112  int  verbose = 0;   /* flag for verbose output */
113
114  while ((currArg = getopt(argc, argv, "hm:s:v")) >= 0)  /* parse command line */
115    switch (currArg)
116    {
117      case 'h' :
118        fprintf(stderr, UsageMsg);
119        exit(0);
120        break;
121      case 'm' :
122        memLen = getNumArg(optarg);
123        break;
124      case 's' :
125        binStart = getNumArg(optarg);
126        break;
127      case 'v' :
128        verbose = 1;
129        break;
130      default :
131        fprintf(stderr, UsageMsg);
132        exit(1);
133        break;
134    } /* switch */
135
136  flag = 0;
137
138  for (argCount = 1; argCount < argc; argCount++)
139    if (argv[argCount][0] == '-')
140    {
141      if (argv[argCount][1] == 's')
142        argCount++;
143    }
144    else if (flag)  /* we already have the input file => output file */
145    {
146      if ((fpOut = fopen(argv[argCount], "w")) == NULL)
147      {
148        fprintf(stderr, "%s: can't open %s\n", progName, argv[argCount]);
149        exit(1);
150      }
151    }
152    else /* input file */
153    {
154      if ((fpIn = fopen(argv[argCount], "r")) == NULL)
155      {
156        fprintf(stderr, "%s: can't open %s\n", progName, argv[argCount]);
157        exit(1);
158      }
159      flag = 1;
160    }
161
162  /*** begin: Conversion to Bootimg */
163
164  /*** File Header */
165
166  if (verbose)
167    fprintf(stderr, "\nBoot Image File Header:\n\n");
168
169  bootimgFileHdr.magicNum = BOOT_IMAGE_MAGIC;  /* 4 bytes - magic number     */
170  bootimgFileHdr.flagsLen = NON_VENDOR_LEN;    /* 4 bytes - flags and length */
171  bootimgFileHdr.locAddr = getSegOff(binStart - BOOTIMG_HDR_SIZE);
172                               /* 4 bytes - location address in ds:bx format */
173  bootimgFileHdr.execAddr = getSegOff(binStart);
174                                /* 4 bytes - execute address in cs:ip format */
175
176  if (verbose)
177  {
178    fprintf(stderr, ">> location address in ds:bx format: %04x:%04x\n",
179              getSeg(bootimgFileHdr.locAddr), getOff(bootimgFileHdr.locAddr));
180    fprintf(stderr, ">>  execute address in cs:ip format: %04x:%04x\n",
181              getSeg(bootimgFileHdr.execAddr), getOff(bootimgFileHdr.execAddr));
182  }
183
184  /*** Write File Header to output file */
185
186  fwrite((void *)(& bootimgFileHdr), sizeof(FileHeader), 1, fpOut);
187
188  /*** Sections */
189
190  if (verbose)
191    fprintf(stderr, "\nCode Section:\n\n");
192
193  imageInfo.flagsTagsLens = 0x04000004;
194                       /* flags, vendor's tags, vendor and non-vendor lengths */
195  imageInfo.loadAddr      = binStart;                        /* load address  */
196
197  rewind(fpIn);
198  fseek(fpIn, 0, SEEK_END);
199  nRead = ftell(fpIn);
200  rewind(fpIn);
201  padSize = LAST_BLOCK_SIZE - (nRead % LAST_BLOCK_SIZE);
202  imageInfo.imageLength  = nRead + padSize;                  /* image length  */
203  imageInfo.memoryLength = (memLen != 0) ? memLen : imageInfo.imageLength;
204                                                             /* memory length */
205
206  fwrite((void *)(&imageInfo), sizeof(LoadingInfo), 1, fpOut);
207
208  if (verbose)
209  {
210    fprintf(stderr, ">>  load address: 0x%08lx\n", imageInfo.loadAddr);
211    fprintf(stderr, ">>  image length: 0x%08lx\n", imageInfo.imageLength);
212    fprintf(stderr, ">> memory length: 0x%08lx\n\n", imageInfo.memoryLength);
213  }
214
215  nRead = BOOTIMG_HDR_SIZE - sizeof(FileHeader) - sizeof(LoadingInfo);
216  memset((void *)auxBuf, 0x00, nRead);
217  fwrite((void *)auxBuf, 1, nRead, fpOut);
218
219  nRead = fread((void *)auxBuf, 1, BUFFER_BLOCK_SIZE, fpIn);
220
221  while (!feof(fpIn))
222  {
223    fwrite((void *)auxBuf, BUFFER_BLOCK_SIZE, 1, fpOut);
224    nRead = fread((void *)auxBuf, 1, BUFFER_BLOCK_SIZE, fpIn);
225  }
226
227  fwrite((void *)auxBuf, 1, nRead, fpOut);
228
229  memset((void *)auxBuf, 0x00, padSize);
230  fwrite((void *)auxBuf, 1, padSize, fpOut);
231
232  fclose(fpOut);
233  fclose(fpIn);
234
235  /*** end: Conversion to Bootimg */
236 
237  exit(0);
238
239} /* main */
Note: See TracBrowser for help on using the repository browser.