summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/i386/pc386/tools/bin2boot.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/i386/pc386/tools/bin2boot.c')
-rw-r--r--c/src/lib/libbsp/i386/pc386/tools/bin2boot.c239
1 files changed, 239 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/i386/pc386/tools/bin2boot.c b/c/src/lib/libbsp/i386/pc386/tools/bin2boot.c
new file mode 100644
index 0000000000..f8eaa0faea
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/tools/bin2boot.c
@@ -0,0 +1,239 @@
+/*-------------------------------------------------------------------------+
+| bin2boot.c v1.1 - PC386 BSP - 1997/08/18
++--------------------------------------------------------------------------+
+| This file contains the i386 binary to boot image filter.
++--------------------------------------------------------------------------+
+| (C) Copyright 1997 -
+| - NavIST Group - Real-Time Distributed Systems and Industrial Automation
+|
+| http://pandora.ist.utl.pt
+|
+| Instituto Superior Tecnico * Lisboa * PORTUGAL
++--------------------------------------------------------------------------+
+| Disclaimer:
+|
+| This file is provided "AS IS" without warranty of any kind, either
+| expressed or implied.
++--------------------------------------------------------------------------*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "bytetype.h"
+#include "bootimg.h"
+
+/*-------------------------------------------------------------------------+
+| Constants
++--------------------------------------------------------------------------*/
+#define SEG_MASK 0xffff0000
+ /* Mask for segment part of seg:off address. */
+#define OFF_MASK 0x0000ffff
+ /* Mask for offset part of seg:off address. */
+#define DEFAULT_START_ADDR 0x10200 /* Default start address for binary. */
+#define BOOTIMG_HDR_SIZE 0x0200 /* Size of output file header. */
+#define BUFFER_BLOCK_SIZE 0x1000 /* Size of transfer buffer size. */
+#define LAST_BLOCK_SIZE 0x0200
+ /* The output file must have a size multiple of this value. */
+
+
+/*-------------------------------------------------------------------------+
+| Macros
++--------------------------------------------------------------------------*/
+#define getSeg(x) (Word)((x) >> 16)
+ /* Return seg part (Word) of a seg:off address (DWord). */
+
+#define getOff(x) (Word)((x) & OFF_MASK)
+ /* Return off part (Word) of a seg:off address (DWord). */
+
+#define getSegOff(x) ((((x) & SEG_MASK) << 12) + ((x) & OFF_MASK))
+ /* Converts a flat address to a seg:off address. */
+
+/*-------------------------------------------------------------------------+
+| Global Variables
++--------------------------------------------------------------------------*/
+const char UsageMsg[] = "\
+Usage: bin2boot [<infile> [<outfile>]] [-s <start_address>] [-v]\n\
+\n\
+ <infile> : input file name\n\
+ <outfile> : output file name\n\
+ -s <outfile> : start address of binary image\n\
+ -m <size> : actual size (for compressed images)\n\
+ -v : verbose output\n"; /* Usage message. */
+
+
+/*-------------------------------------------------------------------------+
+| External Prototypes (for use with getopt)
++--------------------------------------------------------------------------*/
+extern char *optarg;
+
+int getopt(int, char *const[], const char *);
+
+
+/*-------------------------------------------------------------------------+
+| Auxiliary Functions
++--------------------------------------------------------------------------*/
+static DWord
+getNumArg(char *arg)
+{
+ char *dummy;
+
+ if (arg[0] == '0')
+ if ((arg[1] == 'x') || (arg[1] == 'X')) /* Hexadecimal */
+ return (DWord)strtol(arg, &dummy, 16);
+ else /* Octal */
+ return (DWord)strtol(arg, &dummy, 8);
+ else /* Decimal */
+ return (DWord)strtol(arg, &dummy, 10);
+} /* getNumArg */
+
+
+/*-------------------------------------------------------------------------+
+| Main
++--------------------------------------------------------------------------*/
+void main(int argc, char *argv[])
+{
+ FileHeader bootimgFileHdr; /* Output file header. */
+ LoadingInfo imageInfo; /* Section header. */
+ Byte auxBuf[BUFFER_BLOCK_SIZE]; /* */
+ DWord nRead; /* Number of bytes read. */
+ Word padSize; /* Size of padding at end of file. */
+
+ char *progName = argv[0]; /* Program name for errors. */
+ FILE *fpIn = stdin;
+ FILE *fpOut = stdout;
+ DWord binStart = DEFAULT_START_ADDR; /* Start address of image. */
+ DWord memLen = 0; /* Real length for compressed images. */
+
+ char currArg;
+ int argCount;
+ int flag; /* general purpose flag */
+ int verbose = 0; /* flag for verbose output */
+
+ while ((currArg = getopt(argc, argv, "hm:s:v")) >= 0) /* parse command line */
+ switch (currArg)
+ {
+ case 'h' :
+ fprintf(stderr, UsageMsg);
+ exit(0);
+ break;
+ case 'm' :
+ memLen = getNumArg(optarg);
+ break;
+ case 's' :
+ binStart = getNumArg(optarg);
+ break;
+ case 'v' :
+ verbose = 1;
+ break;
+ default :
+ fprintf(stderr, UsageMsg);
+ exit(1);
+ break;
+ } /* switch */
+
+ flag = 0;
+
+ for (argCount = 1; argCount < argc; argCount++)
+ if (argv[argCount][0] == '-')
+ {
+ if (argv[argCount][1] == 's')
+ argCount++;
+ }
+ else if (flag) /* we already have the input file => output file */
+ {
+ if ((fpOut = fopen(argv[argCount], "w")) == NULL)
+ {
+ fprintf(stderr, "%s: can't open %s\n", progName, argv[argCount]);
+ exit(1);
+ }
+ }
+ else /* input file */
+ {
+ if ((fpIn = fopen(argv[argCount], "r")) == NULL)
+ {
+ fprintf(stderr, "%s: can't open %s\n", progName, argv[argCount]);
+ exit(1);
+ }
+ flag = 1;
+ }
+
+ /*** begin: Conversion to Bootimg */
+
+ /*** File Header */
+
+ if (verbose)
+ fprintf(stderr, "\nBoot Image File Header:\n\n");
+
+ bootimgFileHdr.magicNum = BOOT_IMAGE_MAGIC; /* 4 bytes - magic number */
+ bootimgFileHdr.flagsLen = NON_VENDOR_LEN; /* 4 bytes - flags and length */
+ bootimgFileHdr.locAddr = getSegOff(binStart - BOOTIMG_HDR_SIZE);
+ /* 4 bytes - location address in ds:bx format */
+ bootimgFileHdr.execAddr = getSegOff(binStart);
+ /* 4 bytes - execute address in cs:ip format */
+
+ if (verbose)
+ {
+ fprintf(stderr, ">> location address in ds:bx format: %04x:%04x\n",
+ getSeg(bootimgFileHdr.locAddr), getOff(bootimgFileHdr.locAddr));
+ fprintf(stderr, ">> execute address in cs:ip format: %04x:%04x\n",
+ getSeg(bootimgFileHdr.execAddr), getOff(bootimgFileHdr.execAddr));
+ }
+
+ /*** Write File Header to output file */
+
+ fwrite((void *)(& bootimgFileHdr), sizeof(FileHeader), 1, fpOut);
+
+ /*** Sections */
+
+ if (verbose)
+ fprintf(stderr, "\nCode Section:\n\n");
+
+ imageInfo.flagsTagsLens = 0x04000004;
+ /* flags, vendor's tags, vendor and non-vendor lengths */
+ imageInfo.loadAddr = binStart; /* load address */
+
+ rewind(fpIn);
+ fseek(fpIn, 0, SEEK_END);
+ nRead = ftell(fpIn);
+ rewind(fpIn);
+ padSize = LAST_BLOCK_SIZE - (nRead % LAST_BLOCK_SIZE);
+ imageInfo.imageLength = nRead + padSize; /* image length */
+ imageInfo.memoryLength = (memLen != 0) ? memLen : imageInfo.imageLength;
+ /* memory length */
+
+ fwrite((void *)(&imageInfo), sizeof(LoadingInfo), 1, fpOut);
+
+ if (verbose)
+ {
+ fprintf(stderr, ">> load address: 0x%08lx\n", imageInfo.loadAddr);
+ fprintf(stderr, ">> image length: 0x%08lx\n", imageInfo.imageLength);
+ fprintf(stderr, ">> memory length: 0x%08lx\n\n", imageInfo.memoryLength);
+ }
+
+ nRead = BOOTIMG_HDR_SIZE - sizeof(FileHeader) - sizeof(LoadingInfo);
+ memset((void *)auxBuf, 0x00, nRead);
+ fwrite((void *)auxBuf, 1, nRead, fpOut);
+
+ nRead = fread((void *)auxBuf, 1, BUFFER_BLOCK_SIZE, fpIn);
+
+ while (!feof(fpIn))
+ {
+ fwrite((void *)auxBuf, BUFFER_BLOCK_SIZE, 1, fpOut);
+ nRead = fread((void *)auxBuf, 1, BUFFER_BLOCK_SIZE, fpIn);
+ }
+
+ fwrite((void *)auxBuf, 1, nRead, fpOut);
+
+ memset((void *)auxBuf, 0x00, padSize);
+ fwrite((void *)auxBuf, 1, padSize, fpOut);
+
+ fclose(fpOut);
+ fclose(fpIn);
+
+ /*** end: Conversion to Bootimg */
+
+ exit(0);
+
+} /* main */