/* * Simplyfied version of original bin2boot */ #include #include #include #include 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; } int main(int argc, char* argv[]) { 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; /* 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, "wb"); 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); 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; } /* Copy the first image */ optind++; ifile = argv[optind]; ifp = fopen(ifile,"rb"); 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,"rb"); 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; }