forked from Imagelibrary/rtems
400 lines
8.3 KiB
C
400 lines
8.3 KiB
C
|
|
/*
|
|
* Simplyfied version of original bin2boot
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
|
|
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;
|
|
}
|
|
|
|
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;
|
|
}
|