📄 flasher.c
字号:
* Read in entire contents of file.
*/
if (fread(buffer, 1, fileSize, fp) == 0)
{
fprintf(stderr, "flasher: Failed to read from %s\n", fileName);
exit(1);
}
/*
* Check have read entire file.
*/
if (fgetc(fp) != EOF)
{
fprintf(stderr, "flasher: Incomplete read from %s\n", fileName);
exit(1);
}
fclose(fp);
/*
* Tokenise buffer into white space separated arguments.
*/
for (s = strtok(buffer, " \n\r\t"); s; s = strtok(NULL, " \n\r\t"))
{
(*argc)++;
argv = reallocate(argv, (*argc + 1) * sizeof(char*));
argv[*argc - 1] = allocate(strlen(s) + 1);
strcpy(argv[*argc - 1], s);
}
if (*argc)
{
argv[*argc] = NULL;
}
free(buffer);
return argv;
}
/*
* Add an image file to the given list.
*/
static void addImage(image_t* head, image_t* image)
{
image->prev = head->prev;
image->next = head;
head->prev->next = image;
head->prev = image;
}
/*
* Routine to parse the command line.
*/
static void processCmdLine(int argc, char* argv[], int isOptionFile)
{
int c;
int slot;
image_t* image;
char* ptr;
if (isOptionFile)
{
optind = 0; /* Do not skip argv[0] */
}
else
{
if (argc < 2)
{
usage("");
}
}
/* We look for long options before using getopt to process the short ones.
Any long options recognised are replaced with -[ to be ignored by getopt
short argument processing.
*/
for (c = 0; c < argc; c++)
{
if (*argv[c] == '-' && strlen(argv[c]) > 2)
{
/* This looks like a long option - see if it matches any of the valid ones */
if (!strcmp(argv[c], "-fs"))
{
/* Fail-safe image option */
argv[c++] = "-[";
failsafeImage = (image_t*)allocate(sizeof(image_t));
failsafeImage->fileName = (char*)malloc(strlen(argv[c]) + 1);
strcpy((char*)failsafeImage->fileName, argv[c]);
failsafeImage->slot = FAILSAFE_SLOT;
argv[c] = "-[";
continue;
}
else if (!strcmp(argv[c], "-bootsep"))
{
/* Separate FLASH blocks containing boot code from application code so
* they can be protected.
*/
argv[c] = "-[";
separateBootAndAppFlashBlocks = 1;
continue;
}
}
}
while ((c = getopt(argc, argv, "p:d:ev:s:i:I:b:r:f:t:[")) != EOF)
{
switch (c)
{
case 'b':
slot = getSlot(optarg);
bootList = reallocate(bootList, (slotsToMakeBootable + 1) * sizeof(int));
bootList[slotsToMakeBootable++] = slot;
break;
case 'd':
slot = getSlot(optarg);
deleteList = reallocate(deleteList, (slotsToDelete + 1) * sizeof(int));
deleteList[slotsToDelete++] = slot;
break;
case 'e':
eraseFlag = 1;
break;
case 'f':
if (optionFile)
{
usage("Cannot specify multiple -f");
}
optionFile = (const char*)optarg;
optionFileArgv = inputOptionFile(optionFile, &optionFileArgc);
break;
case 'p':
if (binDump)
{
usage("Cannot specify -p with -r");
}
romProgram = 1;
romFile = (const char*)optarg;
{
char* addrPtr;
if ((addrPtr = strchr(optarg, '@')))
{
binaryBaseAddr = getAddress(addrPtr + 1);
*addrPtr = 0;
}
}
break;
case 'r':
if (romProgram)
{
usage("Cannot specify -p with -r");
}
binDump = 1;
romFile = (const char*)optarg;
break;
case 'i':
image = (image_t*)allocate(sizeof(image_t));
image->fileName = strtok(optarg, "@");
ptr = strtok(NULL, "@");
if (!ptr)
{
image->slot = ANY_SLOT;
}
else
{
image->slot = getSlot(ptr);
}
addImage(&images, image);
break;
case 's':
image = (image_t*)allocate(sizeof(image_t));
image->fileName = (const char*)optarg;
image->slot = ANY_SLOT;
addImage(&bootStraps, image);
break;
case 't':
if (target)
{
usage("Cannot specify multiple -t");
}
if ((target = flashGetTarget(optarg)) == NULL)
{
usage("Unrecognised target board");
}
break;
case 'v':
image = (image_t*)allocate(sizeof(image_t));
image->fileName = (const char*)optarg;
image->slot = ANY_SLOT;
addImage(&bootVectors, image);
break;
case '[':
/* This is a replaced long option - ignore it */
break;
default:
usage("Unrecognised command line switch");
break;
}
}
if ((bootStraps.next != bootStraps.next) || (bootVectors.next != bootVectors.next) ||
(images.next != images.next) || deleteList || bootList || failsafeImage)
{
if (romProgram || binDump)
{
usage("Cannot mix -p or -r with any other options");
}
}
if ((argc > 0) && (optind != argc))
{
usage("Extra characters on command line");
}
}
#endif /* !SFXIMAGENAME */
/*
* Routine used by determineProgramming(), which proceses a new boot vector
* file.
*/
static void processBootVector(image_t* image, bootPages_t* bootPages)
{
FILE* fp;
fileHeader_t header;
imageControl_t* imageInfo;
unsigned int loadAddress;
/*
* Open up the specified image file.
*/
if (!(fp = fopen(image->fileName, "rb")))
{
fprintf(stderr, "flasher: Failed to open %s\n", image->fileName);
exit(1);
}
/*
* Read in the header.
*/
if (fread(&header, sizeof(header), 1, fp) != 1)
{
fprintf(stderr, "flasher: Failed to read header from %s\n", image->fileName);
exit(1);
}
/*
* It should have the correct magic number.
*/
if (header.magic != IMAGE_FILE_MAGIC)
{
fprintf(stderr, "flasher: Invalid image in %s\n", image->fileName);
exit(1);
}
imageInfo = &header.imageInfo;
/*
* Check the CPU is sane.
*/
if ((imageInfo->CPU & FLASH_CPU_MASK) >= FLASH_MAX_CPUS)
{
fprintf(stderr, "flasher: Invalid CPU number for bootvector in %s\n", image->fileName);
exit(1);
}
/*
* Boot vectors must contain just 1 section.
*/
if (imageInfo->numSections != 1)
{
fprintf(stderr, "flasher: Invalid number of bootvector sections in %s (%d > 1)\n",
image->fileName, imageInfo->numSections);
exit(1);
}
printf("Placing bootvector for CPU %d (%s)\n", imageInfo->CPU & FLASH_CPU_MASK, imageInfo->description);
/*
* And they must fit!
*/
if (imageInfo->sections[0].length >= FLASH_BOOT_VECTOR_SIZE)
{
fprintf(stderr, "flasher: Invalid size of bootvector section in %s (0x%08x > 0x%08x)\n",
image->fileName, imageInfo->sections[0].length, FLASH_BOOT_VECTOR_SIZE);
exit(1);
}
/*
* Work out where it should go, and check the header agrees.
*/
#if defined(__mb390__) || defined(__mb424__) || defined(__mb435__)
loadAddress = (unsigned int)0x7FFFFF00;
#else
loadAddress = ((imageInfo->CPU & FLASH_CPU_MASK) * FLASH_BOOT_VECTOR_SIZE) + FLASH_BASE;
#endif
switch (imageInfo->sections[0].type & PLACEMENT_TYPE_MASK)
{
case PLACEMENT_TYPE_ANYWHERE:
break;
case PLACEMENT_TYPE_INPLACE:
if ((loadAddress != imageInfo->sections[0].destinationAddress) && (loadAddress != imageInfo->entryAddress))
{
fprintf(stderr, "flasher: Invalid bootvector in %s\n", image->fileName);
exit(1);
}
break;
default:
fprintf(stderr, "flasher: Unsupported bootvector placement type in %s\n", image->fileName);
exit(1);
break;
}
/*
* All looks OK, so read the code into the new boot page.
*/
if (fread(&bootPages->bootVectors[imageInfo->CPU & FLASH_CPU_MASK], imageInfo->sections[0].length, 1, fp) != 1)
{
fprintf(stderr, "flasher: Failed to read from %s\n", image->fileName);
exit(1);
}
#if !(defined(__mb390__) || defined(__mb424__) || defined(__mb435__))
/*
* Place the description too (if not an STb5301).
*/
strncpy(bootPages->bootVectorDescriptions[imageInfo->CPU & FLASH_CPU_MASK], imageInfo->description, FLASH_DESC_LEN);
#endif
/*
* All done, so close file.
*/
fclose(fp);
}
/*
* Routine to relocate an ELF image.
*/
static void processElfRelocs(unsigned char* image,
unsigned int baseAddress,
unsigned int architecture,
reloc_t* relocs,
size_t numRelocs,
symb_t* symbs,
size_t numSymbs)
{
int i;
reloc_t* reloc;
unsigned int value = 0;
unsigned int symbol;
switch (architecture)
{
case FLASH_CPU_ARCH_LX:
case FLASH_CPU_ARCH_SH4:
break;
default:
fprintf(stderr, "flasher: Unsupported architecture (%d)\n", architecture);
exit(1);
}
for (i = 0; i < numRelocs; i++)
{
reloc = relocs + i;
switch (reloc->info & 0xff)
{
case R_SH_DIR32:
case R_LX_32:
case R_LX_JMP_SLOT:
symbol = reloc->info >> 8;
if (symbol >= numSymbs)
{
fprintf(stderr, "flasher: Invalid relocation symbol reference (%d)\n", symbol);
exit(1);
}
value = baseAddress + symbs[symbol].value + reloc->addend;
break;
case R_SH_RELATIVE:
case R_LX_REL32:
value = baseAddress + reloc->addend;
break;
default:
fprintf(stderr, "Unsupported relocation (%d)\n", reloc->info & 0xff);
exit(1);
}
*(unsigned int*)(image + reloc->offset) = value;
}
}
/*
* Routine used by determineProgramming(), which processes a new bootstrap file.
*/
static void processBootStrap(image_t* image, bootPages_t* bootPages, int phase)
{
FILE* fp;
fileHeader_t header;
imageControl_t* imageInfo;
buffer_t* buffer;
buffer_t* update;
buffer_t* relocInfo = NULL;
unsigned int bootStrapAddress;
imageSection_t* imageSections;
int i;
/*
* Open the image file.
*/
if (!(fp = fopen(image->fileName, "rb")))
{
fprintf(stderr, "flasher: Failed to open %s\n", image->fileName);
exit(1);
}
/*
* Read in the header.
*/
if (fread(&header, sizeof(header), 1, fp) != 1)
{
fprintf(stderr, "flasher: Failed to read header from %s\n", image->fileName);
exit(1);
}
/*
* It should have the correct magic number.
*/
if (header.magic != IMAGE_FILE_MAGIC)
{
fprintf(stderr, "flasher: Invalid image in %s\n", image->fileName);
exit(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -