diff options
Diffstat (limited to 'c/src/lib/libbsp/i386/pc386/tools/bin2boot.c')
-rw-r--r-- | c/src/lib/libbsp/i386/pc386/tools/bin2boot.c | 586 |
1 files changed, 401 insertions, 185 deletions
diff --git a/c/src/lib/libbsp/i386/pc386/tools/bin2boot.c b/c/src/lib/libbsp/i386/pc386/tools/bin2boot.c index d8d19b4166..a47ca2cee3 100644 --- a/c/src/lib/libbsp/i386/pc386/tools/bin2boot.c +++ b/c/src/lib/libbsp/i386/pc386/tools/bin2boot.c @@ -1,198 +1,414 @@ -/*-------------------------------------------------------------------------+ -| bin2boot.c v1.0 - PC386 BSP - 1998/04/09 -+--------------------------------------------------------------------------+ -| 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 "Image.h" -#include "Header.h" -#include "bytetype.h" + +/* + * Simplyfied version of original bin2boot + */ #include <stdio.h> #include <stdlib.h> +#include <unistd.h> +#include <memory.h> -/*-------------------------------------------------------------------------+ -| Constants -+--------------------------------------------------------------------------*/ - -#define MAX_IMAGES 15 - -/*-------------------------------------------------------------------------+ -| Global Variables -+--------------------------------------------------------------------------*/ - -// Help message for users -const char UsageMsg[] = "\ -Usage: bin2boot <outFile> <locAddr> <inFile1> <startAddr1> <memSize1> \\\n\ - [<infile2> <startAddr2> <memSize2>][...][-v][-h][-?]\n\ -\n\ -<outFile> : output file name (mandatory)\n\ -<locAddr> : location address in memory of image header (mandatory)\n\ -<inFileX> : name of Xth input file\n\ -<startAddrX> : start address of Xth image\n\ -<memSizeX> : actual size (for compressed images), use 0 if uncompressed\n\ --v : verbose output\n\ --h, -? : this help message\n\ -\n\ -At least one set of <inFile> <startAddr> and <memSize> is mandatory!\n\ -<locAddr>, <startAddrX> and <memSizeX> can be in Decimal, Hexadecimal or Octal.\n\ -The maximum number of input files is 15.\n"; - -/*-------------------------------------------------------------------------+ -| 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 */ +static unsigned char buf[512]; + +static void usage(void) +{ + printf("usage: bin2boot [-h][-v] <outFile> <headerAddr> \n"); + printf("<imFile1> <imAddr1> <imSize1> [<imFile2> <imAddr2> <imSize2>]\n"); + printf("this function makes image bootable by netboot\n"); + printf("from one or two binary images\n"); + printf("-h - prints this message\n"); + printf("-v - verbose output\n"); + printf("outFile - output file\n"); + printf("headerAddr - address to place header in memory\n"); + printf(" it should be below or equal 0x97e00\n"); + printf("imFile1 - first image\n"); + printf("imAddr1 - its start address, image has to be placed whole\n"); + printf(" below 0x98000 and should not overlap with header\n"); + printf("imSize1 - actual size of compressed image, 0 for uncompressed\n"); + printf("imFile2 - second image\n"); + printf("imAddr2 - its start address\n"); + printf("imSize2 - actual size of compressed image, 0 for uncompressed\n"); + + return; +} -/*-------------------------------------------------------------------------+ -| Main -+--------------------------------------------------------------------------*/ int main(int argc, char* argv[]) { - Image img[MAX_IMAGES]; /* array to store up to MAX_IMAGE images */ - Header hdr; /* boot image file header */ - FILE* outFile; /* boot image file stream */ - char* outFileName; /* name of boot image file */ + int c, verbose; + extern int optind; + FILE *ofp, *ifp; + unsigned long headerAddr, addr1, addr2; + int size1, size2, len1, len2, len, imageCnt, cnt; + char *ofile, *ifile, *end; + + verbose = 0; - int argPos = 1, numImages, i; - int verboseFlag = 0, helpFlag = 0; /* flags for command line options */ + /* parse command line options */ + while ((c = getopt(argc, argv, "hv")) >= 0) + { + switch (c) + { + case 'v': + verbose = 1; + break; + case 'h': + usage(); + return 0; + default: + usage(); + return 1; + } + } + + if((argc - optind) != 8 && (argc - optind) != 5) + { + usage(); + return 1; + } + + ofile = argv[optind]; + ofp = fopen(ofile, "w"); + if(ofp == NULL) + { + fprintf(stderr, "unable to open file %s\n", ofile); + return 1; + } + + /* + * Layout is very simple first 512 is header shared by all + * images, then images at 512 bytes border + */ + + /* Fill buffer with 0's */ + memset(buf, 0, sizeof(buf)); + + fwrite(buf, 1, sizeof(buf), ofp); - /*-------------------------------------------------------------------------+ - | Parse command line arguments and options - +-------------------------------------------------------------------------*/ + optind++; + headerAddr = strtoul(argv[optind], &end, 0); + if(end == argv[optind]) + { + fprintf(stderr, "bad headerAddr %s\n", argv[optind]); + fclose(ofp); + return 1; + } + + if(headerAddr > 0x97e00) + { + fprintf(stderr, "headerAddr is too high 0x%08lx\n", headerAddr); + fclose(ofp); + return 1; + } - { - char opt; - - /* parse command line options */ - while ((opt = getopt(argc, argv, "vh?")) >= 0) - { - argPos++; - switch (opt) - { - case 'v' : verboseFlag = 1; break; - case 'h' : case '?' : helpFlag = 1; break; - } - } - } - - if (helpFlag) - { - fprintf(stderr, "%s\n", UsageMsg); - if (argc == 2) - exit(0); - } - - numImages = (argc - argPos - 2) / 3; - - if (numImages < 1) - { - fprintf(stderr, - "ERROR!!! Not enough command line arguments.\n\n%s\n", - UsageMsg); - exit(1); - } - if (numImages > 15) - { - fprintf(stderr, "ERROR!!! Too many input files.\n\n%s\n", UsageMsg); - exit(1); - } - - newHeader(&hdr); /* initialize hdr */ - - argPos = 1; - - while (argv[argPos][0] == '-') argPos++; /* discard options */ - if(!(outFile = fopen((outFileName = argv[argPos++]), "w"))) - { - fprintf(stderr, - "ERROR!!! While opening file '%s' for output.\n", - outFileName); - exit(1); - } - reserveSpaceHeader(outFile); - - while (argv[argPos][0] == '-') argPos++; /* discard options */ - setLocAddrHeader(&hdr, getNumArg(argv[argPos++])); - - /*-------------------------------------------------------------------------+ - | Parse command line arguments concerning images - +-------------------------------------------------------------------------*/ - - for(i = 0; i < numImages; i++) - { - newImage(&img[i]); - while (argv[argPos][0] == '-') argPos++; /* discard options */ - setImageFile(&img[i], argv[argPos++]); - while (argv[argPos][0] == '-') argPos++; /* discard options */ - setLoadAddrImage(&img[i], getNumArg(argv[argPos++])); - while (argv[argPos][0] == '-') argPos++; /* discard options */ - setMemSizeImage(&img[i], getNumArg(argv[argPos++])); - } - - setLstImgFlagImage(&img[numImages - 1]); /* set flag on last image */ - setExecAddrHeader(&hdr, getLoadAddrImage(&img[0])); - /* boot file execution address is the same as first image's */ - if (verboseFlag) - { - fprintf(stderr, "BootImage file '%s' info:\n\n", outFileName); - fprintHeader(stderr, &hdr); - fprintf(stderr, "\n"); - } - - /*-------------------------------------------------------------------------+ - | Dump images and header to file - +-------------------------------------------------------------------------*/ - - for(i = 0; i < numImages; i++) - { - addImageToHeader(&hdr, &img[i]); - dumpImageToFileAndPad(outFile, &img[i]); - - if (verboseFlag) - fprintImage(stderr, &img[i]); - - /* kill image. we don't need anymore and should free its resources */ - killImage(&img[i]); - } - - dumpHeaderToFile(outFile, &hdr); - - fclose(outFile); - - exit(0); -} /* main */ + /* Copy the first image */ + optind++; + ifile = argv[optind]; + ifp = fopen(ifile,"r"); + if(ifp == NULL) + { + fprintf(stderr, "unable to open output file %s\n", ifile); + fclose(ofp); + return 1; + } + + optind++; + addr1 = strtoul(argv[optind], &end, 0); + if(end == argv[optind]) + { + fprintf(stderr, "bad image address %s\n", argv[optind]); + fclose(ofp); + return 1; + } + + optind++; + size1 = strtoul(argv[optind], &end, 0); + if(end == argv[optind]) + { + fprintf(stderr, "bad image size %s\n", argv[optind]); + fclose(ofp); + return 1; + } + + + /* Copy first image out and remember its length */ + cnt = 0; + for(;;) + { + len = fread(buf, 1, sizeof(buf), ifp); + + if(len != 0) + { + fwrite(buf, 1, len, ofp); + cnt += sizeof(buf); + + if(len != sizeof(buf)) + { + memset(buf, 0, sizeof(buf) - len); + fwrite(buf, 1, sizeof(buf) - len, ofp); + break; + } + + } + else + { + break; + } + } + + fclose(ifp); + + len1 = cnt; + + if(size1 == 0) + { + size1 = cnt; + } + else + { + memset(buf, 0, sizeof(buf)); + + while(cnt < size1) + { + fwrite(buf, 1, sizeof(buf), ofp); + cnt += sizeof(buf); + } + + size1 = cnt; + } + + + /* Let us check agains overlapping */ + if(!(addr1 >= (headerAddr + sizeof(buf)) || (headerAddr >= addr1+size1))) + { + /* Areas overlapped */ + printf("area overlapping: \n"); + printf("header address 0x%08lx, its memory size 0x%08x\n", + headerAddr, sizeof(buf)); + printf("first image address 0x%08lx, its memory size 0x%08x\n", + addr1, size1); + + fclose(ofp); + return 1; + } + + if((addr1 + size1) > 0x98000) + { + fprintf(stderr, "imAddr1 is too high 0x%08lx\n", addr1); + fclose(ofp); + return 1; + } + + + if(optind == (argc - 1)) + { + imageCnt = 1; + goto writeHeader; + } + + imageCnt = 2; + + /* Copy Second Image */ + optind++; + ifile = argv[optind]; + ifp = fopen(ifile,"r"); + if(ifp == NULL) + { + fprintf(stderr, "unable to open output file %s\n", ifile); + fclose(ofp); + return 1; + } + + optind++; + addr2 = strtoul(argv[optind], &end, 0); + if(end == argv[optind]) + { + fprintf(stderr, "bad image address %s\n", argv[optind]); + fclose(ofp); + return 1; + } + + optind++; + size2 = strtoul(argv[optind], &end, 0); + if(end == argv[optind]) + { + fprintf(stderr, "bad image size %s\n", argv[optind]); + fclose(ofp); + return 1; + } + + /* Copy second image out and remember its length */ + cnt = 0; + for(;;) + { + len = fread(buf, 1, sizeof(buf), ifp); + + if(len != 0) + { + fwrite(buf, len, 1, ofp); + cnt += sizeof(buf); + + if(len != sizeof(buf)) + { + memset(buf, 0, sizeof(buf) - len); + fwrite(buf, 1, sizeof(buf) - len, ofp); + break; + } + } + else + { + break; + } + } + + fclose(ifp); + + len2 = cnt; + + if(size2 == 0) + { + size2 = cnt; + } + else + { + memset(buf, 0, sizeof(buf)); + + while(cnt < size2) + { + fwrite(buf, 1, sizeof(buf), ofp); + cnt += sizeof(buf); + } + + size2 = cnt; + } + + /* Let us check against overlapping */ + if(!((addr2 >= (addr1 + size1) && addr2 >= (headerAddr + sizeof(buf))) || + (addr2 < addr1 && addr2 < headerAddr) || + (addr1 > headerAddr && addr2 > (headerAddr + sizeof(buf)) && + (addr2 + size2) <= addr1) || + (addr1 < headerAddr && addr2 > (addr1 + size1) && + (addr2 + size2) <= headerAddr))) + + { + /* Areas overlapped */ + printf("area overlapping: \n"); + printf("header address 0x%08lx, its memory size 0x%08x\n", + headerAddr, sizeof(buf)); + printf("first image address 0x%08lx, its memory size 0x%08x\n", + addr1, size1); + printf("second image address 0x%08lx, its memory size 0x%08x\n", + addr2, size2); + + fclose(ofp); + return 1; + } + +writeHeader: + + /* We know everything so it is time to write buffer */ + memset(buf, 0, 0x30); + + buf[0x0] = 0x36; + buf[0x1] = 0x13; + buf[0x2] = 0x03; + buf[0x3] = 0x1b; + + buf[0x4] = 4; + + /* Header address in ds:bx format */ + buf[0x8] = headerAddr & 0xf; + buf[0x9] = 0; + buf[0xa] = (headerAddr >> 4) & 0xff; + buf[0xb] = (headerAddr >> 12) & 0xff; + + /* + * Execute address in cs:ip format, which addr1 + */ + buf[0xc] = addr1 & 0xf; + buf[0xd] = 0; + buf[0xe] = (addr1 >> 4) & 0xff; + buf[0xf] = (addr1 >> 12) & 0xff; + + /* Flags, tags and lengths */ + buf[0x10] = 4; + + if(imageCnt == 1) + { + buf[0x13] = 4; + } + + /* Load address */ + buf[0x14] = addr1 & 0xff; + buf[0x15] = (addr1 >> 8) & 0xff; + buf[0x16] = (addr1 >> 16) & 0xff; + buf[0x17] = (addr1 >> 24) & 0xff; + + /* Image Length */ + buf[0x18] = len1 & 0xff; + buf[0x19] = (len1 >> 8) & 0xff; + buf[0x1a] = (len1 >> 16) & 0xff; + buf[0x1b] = (len1 >> 24) & 0xff; + + /* Memory Size */ + buf[0x1c] = size1 & 0xff; + buf[0x1d] = (size1 >> 8) & 0xff; + buf[0x1e] = (size1 >> 16) & 0xff; + buf[0x1f] = (size1 >> 24) & 0xff; + + if(imageCnt != 1) + { + + /* Flags, tags and lengths */ + buf[0x20] = 4; + + buf[0x23] = 4; + + + /* Load address */ + buf[0x24] = addr2 & 0xff; + buf[0x25] = (addr2 >> 8) & 0xff; + buf[0x26] = (addr2 >> 16) & 0xff; + buf[0x27] = (addr2 >> 24) & 0xff; + + /* Image Length */ + buf[0x28] = len2 & 0xff; + buf[0x29] = (len2 >> 8) & 0xff; + buf[0x2a] = (len2 >> 16) & 0xff; + buf[0x2b] = (len2 >> 24) & 0xff; + + /* Memory Size */ + buf[0x2c] = size2 & 0xff; + buf[0x2d] = (size2 >> 8) & 0xff; + buf[0x2e] = (size2 >> 16) & 0xff; + buf[0x2f] = (size2 >> 24) & 0xff; + } + + rewind(ofp); + + fwrite(buf, 1, 0x30, ofp); + + fclose(ofp); + + if(verbose) + { + printf("header address 0x%08lx, its memory size 0x%08x\n", + headerAddr, sizeof(buf)); + printf("first image address 0x%08lx, its memory size 0x%08x\n", + addr1, size1); + printf("second image address 0x%08lx, its memory size 0x%08x\n", + addr2, size2); + } + + return 0; +} + + + + + + + + |