📄 generateimage.c
字号:
/*******************************************************************************
*
* Copyright 2003,MARVELL SEMICONDUCTOR ISRAEL, LTD.
* THIS CODE CONTAINS CONFIDENTIAL INFORMATION OF MARVELL.
* NO RIGHTS ARE GRANTED HEREIN UNDER ANY PATENT, MASK WORK RIGHT OR COPYRIGHT
* OF MARVELL OR ANY THIRD PARTY. MARVELL RESERVES THE RIGHT AT ITS SOLE
* DISCRETION TO REQUEST THAT THIS CODE BE IMMEDIATELY RETURNED TO MARVELL.
* THIS CODE IS PROVIDED "AS IS". MARVELL MAKES NO WARRANTIES, EXPRESSED,
* IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, COMPLETENESS OR PERFORMANCE.
*
* MARVELL COMPRISES MARVELL TECHNOLOGY GROUP LTD. (MTGL) AND ITS SUBSIDIARIES,
* MARVELL INTERNATIONAL LTD. (MIL), MARVELL TECHNOLOGY, INC. (MTI), MARVELL
* SEMICONDUCTOR, INC. (MSI), MARVELL ASIA PTE LTD. (MAPL), MARVELL JAPAN K.K.
* (MJKK), MARVELL SEMICONDUCTOR ISRAEL. (MSIL), MARVELL TAIWAN, LTD. AND
* SYSKONNECT GMBH.
*
*******************************************************************************/
#include <stdio.h>
#include <string.h>
unsigned long romSize = 0;
unsigned short deviceId = 0;
#define OPTION_ROM_OFFSET 0
#define PNP_EXPANSION_ROM_OFFSET 0x0100
#define PCI_DATA_STRUCTURE_OFFSET 0x001C
#define START_OF_IMAGE 0x0200
#define NUM_OF_DRIVES 8 /* Should be between 1..8 */
#define VENDOR_ID 0x11ab
#define ROM_IMAGE_VERSION 32
#define ROM_IMAGE_SUBVERSION 13
struct optionRomHeader
{
unsigned char signature1;
unsigned char signature2;
unsigned char optionRomLength;
unsigned char initEntryPoint[3];
unsigned char reserved[18];
unsigned short offsetToPciDataStructure;
unsigned short offsetToExpansionRomHeaderStructure;
};
struct pnpExpansionRomHeader
{
unsigned char signature1;
unsigned char signature2;
unsigned char signature3;
unsigned char signature4;
unsigned char structureRevision;
unsigned char length;
unsigned short offsetToNextHeader;
unsigned char reserved1;
unsigned char checksum;
unsigned long deviceIdentifier;
unsigned short manfucaturingString;
unsigned short productNameString;
unsigned char deviceTypeCode[3];
unsigned char deviceIndicators;
unsigned short bootConnectionVector;
unsigned short disconnectVecotr;
unsigned short bootstrapEntryVector;
unsigned short reserved2;
unsigned short staticResourceInformationVector;
};
struct pciDataStructure
{
unsigned char signature1;
unsigned char signature2;
unsigned char signature3;
unsigned char signature4;
unsigned short vendorIdentification;
unsigned short deviceIdentification;
unsigned short pointerToVitalProductData;
unsigned short pciDataStructureLength;
unsigned char pciDataStructureRevision;
unsigned char classCode[3];
unsigned short imageLength;
unsigned short revisionCodeOfCodeAndData;
unsigned char codeType;
unsigned char indicator;
unsigned short reserved;
};
unsigned char image[64*1024]; /* 64 KByte */
unsigned short bcvVector[8];
void initializePnPHeader (int index)
{
struct pnpExpansionRomHeader *pPnpHeader;
unsigned char checkSum;
int temp;
unsigned long combinedDevIdVenId;
/* Initialize PnP expansion header */
pPnpHeader = (struct pnpExpansionRomHeader *) &image[PNP_EXPANSION_ROM_OFFSET + index*32];
memset (pPnpHeader, 0, sizeof(struct pnpExpansionRomHeader));
pPnpHeader->signature1 = '$';
pPnpHeader->signature2 = 'P';
pPnpHeader->signature3 = 'n';
pPnpHeader->signature4 = 'P';
pPnpHeader->structureRevision = 0x01;
pPnpHeader->length = 0x2;
if (index < (NUM_OF_DRIVES -1))
{
pPnpHeader->offsetToNextHeader = PNP_EXPANSION_ROM_OFFSET + (index+1)*32;
}
else
{
pPnpHeader->offsetToNextHeader = 0x0;
}
pPnpHeader->checksum = 0x00;
#if 1
combinedDevIdVenId = (((unsigned long) (VENDOR_ID)) |
((unsigned long) (deviceId << 16)));
#else
combinedDevIdVenId = (((unsigned long) (deviceId)) |
((unsigned long) (VENDOR_ID << 16)));
#endif
pPnpHeader->deviceIdentifier = combinedDevIdVenId;
pPnpHeader->manfucaturingString = 0x0060;
strcpy (&image[0x60], "NeoCreatec TeraExpress");
pPnpHeader->productNameString = 0x200+index*0x10;
strcpy (&image[0x200+index*0x10], "SATA x");
image[0x200+index*0x10+12] = index+'0';
pPnpHeader->deviceTypeCode[0] = 0x00;
pPnpHeader->deviceTypeCode[1] = 0x00;
pPnpHeader->deviceTypeCode[2] = 0x01;
pPnpHeader->deviceIndicators = 0x44;
pPnpHeader->bootConnectionVector = bcvVector[index] + 0x8; /* The 0x8 is to bypas all the C code pushing to stack stuff */
pPnpHeader->disconnectVecotr = 0x0000;
pPnpHeader->bootstrapEntryVector = 0x0;
pPnpHeader->staticResourceInformationVector = 0x0;
/* Calculate PnP exp header checksum */
checkSum = 0;
for (temp = 0 ; temp < sizeof (struct pnpExpansionRomHeader); temp ++)
{
checkSum += image[PNP_EXPANSION_ROM_OFFSET+ temp];
}
pPnpHeader->checksum = (~checkSum) + 1;
checkSum = 0;
for (temp = 0 ; temp < sizeof (struct pnpExpansionRomHeader); temp ++)
{
checkSum += image[PNP_EXPANSION_ROM_OFFSET+ temp];
}
/*printf("PNP Header checksum %x\n",checkSum);*/
}
int main(int argc, char **argv)
{
struct optionRomHeader *pRomHeader;
struct pciDataStructure *pPciDataStructure;
FILE *romImage, *outputImage, *bcvVectorsFile;
unsigned char checkSum;
int temp, pointer, foundAllBCVs = 0;
memset (image, 0, romSize);
if (argc != 5)
{
printf ("Usage - %s <code image> <output file> <BCV Vector Table> <Device ID>\n",argv[0]);
exit (-1);
}
romImage = fopen (argv[1], "rob");
if (!romImage)
{
printf("Can't open file %s\n",argv[1]);
exit (-1);
}
outputImage = fopen (argv[2], "wob");
if (!outputImage)
{
printf("Can't open file %s\n",argv[2]);
exit (-1);
}
bcvVectorsFile = fopen (argv[3], "rob");
if (!romImage)
{
printf("Can't open file %s\n",argv[3]);
exit (-1);
}
printf("Extracting BCV Entry points\n");
while (1)
{
char line[200];
char str1[200], str2[200], str3[200];
char *ret;
int bcvEntry;
ret = fgets (line, 200, bcvVectorsFile);
if (!ret)
{
break;
}
sscanf (line, "%s %s %s", str1, str2, str3);
if (!strncmp (str2, "bcvEntryPoint_ch", strlen("bcvEntryPoint_ch")))
{
unsigned long offset1, offset2;
static int alreadyFound = 0;
int ccc;
for (ccc = 0 ; ccc < strlen(str1) ; ccc++)
{
if ((str1[ccc] == ':') || (str1[ccc] == '*'))
{
str1[ccc] = ' ';
}
}
if (sscanf (str1, "%x %x", &offset1, &offset2) != 2) break;
if (offset1 != 0)
{
break;
}
bcvEntry = str2[strlen("bcvEntryPoint_ch")] - '0';
if ((bcvEntry < 0) || (bcvEntry > 7))
{
break;
}
bcvVector[bcvEntry] = offset2;
alreadyFound ++;
if (alreadyFound == NUM_OF_DRIVES)
{
foundAllBCVs = 1;
}
}
}
fclose (bcvVectorsFile);
if (foundAllBCVs == 0)
{
printf("Couldn't find all BCV Entry points\n");
exit(-1);
}
if (sscanf (argv[4], "%x", &deviceId) != 1)
{
printf("Could not parse Device ID parameters\n");
exit(-1);
}
/* Calculate .com image size */
romSize = 0;
while (1)
{
temp = fgetc (romImage);
if (temp == EOF)
{
break;
}
romSize ++;
}
fclose (romImage);
romImage = fopen (argv[1], "rob");
if (!romImage)
{
printf("Can't open file %s\n",argv[1]);
exit (-1);
}
romSize = romSize + 1024;
romSize = romSize - (romSize % 512);
printf("ROM Size is %d bytes\n",romSize);
/* Initialize option ROM header */
pRomHeader = (struct optionRomHeader *) &image[OPTION_ROM_OFFSET];
memset (pRomHeader, 0, sizeof(struct optionRomHeader));
image[0x40] = ROM_IMAGE_VERSION;
image[0x41] = ROM_IMAGE_SUBVERSION;
pRomHeader->signature1 = 0x55;
pRomHeader->signature2 = 0xaa;
pRomHeader->optionRomLength = romSize / 512;
pRomHeader->offsetToExpansionRomHeaderStructure = PNP_EXPANSION_ROM_OFFSET;
pRomHeader->offsetToPciDataStructure = PCI_DATA_STRUCTURE_OFFSET;
#if 0
pRomHeader->initEntryPoint[0] = 0xE9;
pRomHeader->initEntryPoint[1] = 0xFA; /*0xFA 0x0F --> JMP to 0x1000*/
pRomHeader->initEntryPoint[2] = 0x0F;
#endif
#if 0
pRomHeader->initEntryPoint[0] = 0xE9;
pRomHeader->initEntryPoint[1] = 0xFA; /*0xFA 0x10 --> JMP to 0x1100*/
pRomHeader->initEntryPoint[2] = 0x10;
#endif
#if 0
pRomHeader->initEntryPoint[0] = 0xEB;
pRomHeader->initEntryPoint[1] = 0x5B; /*0x5B 0x00 --> JMP to 0x60*/
pRomHeader->initEntryPoint[2] = 0x00;
#endif
#if 0
pRomHeader->initEntryPoint[0] = 0xEB;
pRomHeader->initEntryPoint[1] = 0x68; /*0x68 0x00 --> JMP to 0x6d*/
pRomHeader->initEntryPoint[2] = 0x00;
#endif
#if 0
pRomHeader->initEntryPoint[0] = 0xE9;
pRomHeader->initEntryPoint[1] = 0xFA; /*0xFA 0x00 --> JMP to 0x100*/
pRomHeader->initEntryPoint[2] = 0x00;
#endif
#if 1
pRomHeader->initEntryPoint[0] = 0xE9;
pRomHeader->initEntryPoint[1] = 0x04; /*0x04 0x03 --> JMP to 0x30a*/
pRomHeader->initEntryPoint[2] = 0x03;
#endif
/* Initialize PCI data structure */
pPciDataStructure = (struct pciDataStructure *) &image[PCI_DATA_STRUCTURE_OFFSET];
memset (pPciDataStructure, 0, sizeof(struct pciDataStructure));
pPciDataStructure->signature1 = 'P';
pPciDataStructure->signature2 = 'C';
pPciDataStructure->signature3 = 'I';
pPciDataStructure->signature4 = 'R';
pPciDataStructure->vendorIdentification = VENDOR_ID;
pPciDataStructure->deviceIdentification = deviceId;
pPciDataStructure->pointerToVitalProductData = 0x0;
pPciDataStructure->pciDataStructureLength = 0x18;
pPciDataStructure->pciDataStructureRevision = 0x0;
pPciDataStructure->classCode[0] = 0x00;
pPciDataStructure->classCode[1] = 0x00; /* Previously 0x04 by SI */
pPciDataStructure->classCode[2] = 0x01;
pPciDataStructure->imageLength = romSize/512;
pPciDataStructure->revisionCodeOfCodeAndData = 0x0001;
pPciDataStructure->codeType = 0x0;
pPciDataStructure->indicator = 0x80; /* Last image in exp. ROM */
for (temp = 0 ; temp < NUM_OF_DRIVES ; temp ++)
{
initializePnPHeader (temp);
}
/* Copy input image to buffer */
pointer = 0;
while (1)
{
static int counter = 0;
temp = fgetc (romImage);
if (temp == EOF)
{
break;
}
if (counter >= START_OF_IMAGE)
{
image[pointer+0x100] = (unsigned char) temp;
}
pointer ++;
counter ++;
}
/* Calculate checksum of whole image */
checkSum = 0;
for (temp = 0 ; temp < romSize ; temp ++)
{
checkSum += image[temp];
}
image[romSize-1] = (~checkSum) + 1;
checkSum = 0;
for (temp = 0 ; temp < romSize ; temp ++)
{
checkSum += image[temp];
}
printf("Checksum of whole image %d\n",checkSum);
/* Write file down */
for (temp = 0 ; temp < (romSize) ; temp ++)
{
fputc (image[temp], outputImage);
}
fclose (romImage);
fclose (outputImage);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -