From 5d18fb057a9158336a79953b88d481c74c6eb0ae Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Sat, 27 Jun 1998 18:51:49 +0000 Subject: PC386 BSP enhancements from Aleksey Romanov (Quality Quorum ). Unfortunately after merging these, the pc386 will not boot using grub for for. It still does not work using netboot for me. Here is his summary of changes: rtems/c/src/lib/libbsp/i386/pc386/Makefile.in Added support for new sub-directory rtems/c/src/lib/libbsp/i386/pc386/bsp_specs Made possible to build COFF image rtems/c/src/lib/libbsp/i386/pc386/console/console.c Added support for serial consoles, selectable by patching binary image, added __assert(), use _IBMPC_inch_sleep() instaed of _IMBPC_inch() rtems/c/src/lib/libbsp/i386/pc386/console/inch.c Added _IMBPC_inch_sleep() rtems/c/src/lib/libbsp/i386/pc386/console/outch.c Oops - just formatting rtems/c/src/lib/libbsp/i386/pc386/include/Makefile.in Added support for new files rtems/c/src/lib/libbsp/i386/pc386/include/bsp.h Added support for new features rtems/c/src/lib/libbsp/i386/pc386/include/pc386uart.h New file: definitions for serial ports rtems/c/src/lib/libbsp/i386/pc386/include/pcibios.h New file: definitions for PCI BIOS rtems/c/src/lib/libbsp/i386/pc386/pc386dev/Makefile.in New file: makefile in new directory rtems/c/src/lib/libbsp/i386/pc386/pc386dev/i386-stub-glue.c New file: i386-stub interface rtems/c/src/lib/libbsp/i386/pc386/pc386dev/i386-stub.c New file: i386-stub itself rtems/c/src/lib/libbsp/i386/pc386/pc386dev/pc386uart.c New file: serial ports rtems/c/src/lib/libbsp/i386/pc386/pc386dev/pcibios.c New file: PCI BIOS support rtems/c/src/lib/libbsp/i386/pc386/start/start.s Commented out DEBUG_EARLY stuff, everything is working fine rtems/c/src/lib/libbsp/i386/pc386/start/start16.s Cleaned up rtems/c/src/lib/libbsp/i386/pc386/startup/bspstart.c Added call to console_resereve_resources rtems/c/src/lib/libbsp/i386/pc386/startup/exit.c Added support for serial console rtems/c/src/lib/libbsp/i386/pc386/startup/ldsegs.s Fixed typo in comments rtems/c/src/lib/libbsp/i386/pc386/tools/Makefile.in Changed to reflect cnages in code rtems/c/src/lib/libbsp/i386/pc386/tools/bin2boot.c Trivialized, problem - I do not know how to make patch remove obsolete files - there are a lot of them there rtems/c/src/lib/libbsp/i386/pc386/tools/binpatch.c New file: utility to do binary patches rtems/c/src/lib/libbsp/i386/pc386/wrapup/Makefile.in Added support for new directory rtems/make/custom/pc386.cfg Add COFF image building --- c/src/lib/libbsp/i386/pc386/tools/bin2boot.c | 586 ++++++++++++++++++--------- 1 file changed, 401 insertions(+), 185 deletions(-) (limited to 'c/src/lib/libbsp/i386/pc386/tools/bin2boot.c') 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 #include +#include +#include -/*-------------------------------------------------------------------------+ -| Constants -+--------------------------------------------------------------------------*/ - -#define MAX_IMAGES 15 - -/*-------------------------------------------------------------------------+ -| Global Variables -+--------------------------------------------------------------------------*/ - -// Help message for users -const char UsageMsg[] = "\ -Usage: bin2boot \\\n\ - [ ][...][-v][-h][-?]\n\ -\n\ - : output file name (mandatory)\n\ - : location address in memory of image header (mandatory)\n\ - : name of Xth input file\n\ - : start address of Xth image\n\ - : 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 and is mandatory!\n\ -, and 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] \n"); + printf(" [ ]\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; +} + + + + + + + + -- cgit v1.2.3