📄 flasher.c
字号:
}
imageInfo = &header.imageInfo;
if ((imageInfo->CPU & FLASH_CPU_MASK) >= FLASH_MAX_CPUS &&
!(imageInfo->CPU & FLASH_IMAGE_TYPE_MASK)
)
{
fprintf(stderr, "flasher: Invalid CPU number for application in %s\n", image->fileName);
exit(1);
}
if ((imageInfo->CPU & FLASH_IMAGE_TYPE_MASK) == FLASH_IMAGE_TYPE_DATA)
{
printf("Placing data image (%s) in image slot %d\n", imageInfo->description, image->slot);
}
else if ((imageInfo->CPU & FLASH_IMAGE_TYPE_MASK) == FLASH_IMAGE_TYPE_RELOC_LIB)
{
printf("Placing relocatable library (%s) in image slot %d\n", imageInfo->description, image->slot);
rlImage = 1;
}
else
{
printf("Placing image for CPU %d (%s) in image slot %d",
imageInfo->CPU & FLASH_CPU_MASK, imageInfo->description, image->slot);
if (image->slot == FAILSAFE_SLOT)
{
printf(" (fail-safe image slot)");
/* Also flag the fail-safe image as bootable */
imageInfo->CPU |= FLASH_BOOT_FLAG;
}
printf("\n");
}
st40Image = ((imageInfo->CPU & FLASH_CPU_ARCH_MASK) == FLASH_CPU_ARCH_SH4);
/*
* Read in all the sections.
* The header is defined to contain a single section (as a place holder) so
* make things easy we rewind the file, and read in all the sections in one
* go.
*/
fseek(fp, -sizeof(imageSection_t), SEEK_CUR);
imageSections = allocate(sizeof(imageSection_t) * imageInfo->numSections);
if (fread(imageSections, sizeof(imageSection_t) * imageInfo->numSections, 1, fp) != 1)
{
fprintf(stderr, "flasher: Failed to read sections from %s\n", image->fileName);
exit(1);
}
if (phase == 0)
{
image->controlStruct = malloc(sizeof(imageControl_t) + ((imageInfo->numSections - 1) * sizeof(imageSection_t)));
/* Copy from the file to our imageControlStruct in RAM */
*image->controlStruct = *imageInfo;
}
/*
* Process each section...
*/
for (section = 0; section < imageInfo->numSections; section++)
{
buffer_t* buffer;
int process_it = 0;
image->controlStruct->sections[section].length = imageSections[section].length;
image->controlStruct->sections[section].destinationAddress =
(unsigned int)(imageSections[section].destinationAddress);
image->controlStruct->sections[section].type = imageSections[section].type & SECTION_TYPE_MASK;
switch (imageSections[section].type & PLACEMENT_TYPE_MASK)
{
case PLACEMENT_TYPE_NONE:
if (phase == 1)
{
image->controlStruct->sections[section].sourceAddress = 0;
}
break;
case PLACEMENT_TYPE_ANYWHERE:
if (phase == 1)
{
image->controlStruct->sections[section].sourceAddress =
findBestFree(imageSections[section].length, MIN_SECTION_ALIGNMENT,
&flashMap, image->slot == -1 ? (unsigned int) bootPages->imageControlDirectoryPtr : 0);
process_it = 1;
}
break;
case PLACEMENT_TYPE_INPLACE_BLANK:
case PLACEMENT_TYPE_INPLACE:
if (phase == 0)
{
image->controlStruct->sections[section].sourceAddress =
(unsigned int)(imageSections[section].sourceAddress);
process_it = 1;
}
break;
default:
fprintf(stderr, "flasher: Unsupported application placement type in %s\n", image->fileName);
exit(1);
break;
}
if ((imageSections[section].type & PLACEMENT_TYPE_MASK) != PLACEMENT_TYPE_NONE)
{
if (process_it)
{
buffer = allocate(sizeof(buffer_t));
buffer->address = image->controlStruct->sections[section].sourceAddress;
buffer->length = image->controlStruct->sections[section].length;
buffer->info.data = (unsigned char*)allocate(buffer->length);
/*
* Setup the image data, either from file or init to 0xff.
*/
if ((imageSections[section].type & PLACEMENT_TYPE_MASK) == PLACEMENT_TYPE_INPLACE_BLANK)
{
memset(buffer->info.data, 0xff, buffer->length);
}
else
{
if (fread(buffer->info.data, buffer->length, 1, fp) != 1)
{
fprintf(stderr, "flasher: Failed to read section data from %s\n", image->fileName);
exit(1);
}
}
/*
* Add the update to the update list.
*/
addBuffer(buffer, &updateList);
/*
* Finally mark this region of FLASH as allocated.
*/
allocBlock = allocate(sizeof(buffer_t));
allocBlock->address = buffer->address;
allocBlock->length = buffer->length;
allocBlock->info.type = MEM_USED;
updateMemMap(allocBlock, &flashMap);
/*
* Map LX_BOOT sections to SKIP when in FLASH, and overwrite entrypoint.
*/
if (image->controlStruct->sections[section].type == SECTION_TYPE_LX_BOOT)
{
image->controlStruct->sections[section].type = SECTION_TYPE_SKIP;
image->controlStruct->entryAddress = image->controlStruct->sections[section].sourceAddress;
}
}
else
{
/*
* Not processing on this pass - seek over the data.
*/
if (fseek(fp, image->controlStruct->sections[section].length, SEEK_CUR) == -1)
{
fprintf(stderr, "flasher: Failed to seek over section data from %s\n", image->fileName);
exit(1);
}
}
}
}
if (phase == 1)
{
/*
* Find room for dir entry, if image->slot is zero, then the whole region is
* free, otherwise, we must abut the existing entries.
* We use imageInfo->numSections-1 here, because a imageControl_t already
* contains one section
*/
entrySize = sizeof(imageControl_t) + ((imageInfo->numSections - 1) * sizeof(imageSection_t));
if (image->slot == FAILSAFE_SLOT)
{
controlStruct = (imageControl_t*)&bootPages->failsafeImageControlStructure;
}
else
{
controlStruct = (imageControl_t*)findBestFree(entrySize, 1, &controlMap, 0);
allocBlock = allocate(sizeof(buffer_t));
allocBlock->address = (unsigned int)controlStruct;
allocBlock->length = entrySize;
allocBlock->info.type = MEM_USED;
updateMemMap(allocBlock, &controlMap);
}
/*
* Fill in the boot control structure, and place the sections.
*
* Set the pointer in the table.
*/
if (image->slot != FAILSAFE_SLOT)
imageDirectoryPages->directory.entries[image->slot] = controlStruct;
/*
* Copy the header from the file into the boot control structure.
*/
*controlStruct = *image->controlStruct;
{
int secNo;
for (secNo = 1; secNo < controlStruct->numSections; secNo++)
controlStruct->sections[secNo] = image->controlStruct->sections[secNo];
}
}
/*
* Free off imageSections - its job is done.
*/
free(imageSections);
}
/*
* Routine to perform the image slot deletes given on the command line with
* '-d'.
*/
static void processDeletes(bootPages_t* bootPages, imageDirectoryPages_t* imageDirectoryPages)
{
int* ptr = deleteList;
int i;
for (i = 0; i < slotsToDelete; i++)
{
printf("Deleting image in slot %d", *ptr);
if (*ptr == FAILSAFE_SLOT)
printf(" (fail-safe image slot)\n");
printf("\n");
deleteSlot(*ptr++, bootPages, imageDirectoryPages);
}
}
/*
* Routine to perform the make bootable requests.
*/
static void processMakeBoots(imageDirectoryPages_t* imageDirectoryPages)
{
int i;
for (i = 0; i < slotsToMakeBootable; i++)
{
makeBootable(imageDirectoryPages, bootList[i]);
}
}
/*
* This routine generates new boot and image pages, loads the image data to be
* blown and creates the update descriptors describing what to do.
*/
static void determineProgramming(bootPages_t* bootPages, imageDirectoryPages_t* imageDirectoryPages,
unsigned int flashSize, flashDevice_t** devices, flashTarget_t* target)
{
#if defined(__mb376__) || defined(__espresso__)
static unsigned char sti5528BootPage[1024] = {
0x01, 0xD0, 0x0B, 0x40,
0x09, 0x00, 0x09, 0x00,
0x00, 0x04, 0x00, 0xA0
};
#endif
image_t* ptr;
buffer_t* buffer;
int phase;
printf("Beginning analysis...\n");
/*
* Create the FLASH memory map, so we can place the user images. This involves
* examining the existing state of the FLASH directories, and building a
* picture of what is in use, and what is not.
*/
createMemoryMap(bootPages, imageDirectoryPages, flashSize);
/*
* Delete any slots we were asked to.
*/
processDeletes(bootPages, imageDirectoryPages);
/*
* We place sections in the following order:
* 1) Boot vectors
* 2) in-place sections for all images
* 3) bootstraps (in-place and then anywhere sections)
* 4) failsafe image anywhere sections
* 5) remaining anywhere sections
*
* In processBootStrap() and processImage() calls the phase parameter is 0 to
* deal with in-place sections, and 1 to deal with anywhere sections.
*/
for (ptr = bootVectors.next; ptr != &bootVectors; ptr = ptr->next)
{
processBootVector(ptr, bootPages);
}
/* Place in-place sections for the failsafe and main application images */
if (failsafeImage)
processImage(failsafeImage, bootPages, imageDirectoryPages, 0, devices, target);
for (ptr = images.next; ptr != &images; ptr = ptr->next)
processImage(ptr, bootPages, imageDirectoryPages, 0, devices, target);
/* Place both in-place and then anywhere sections for the bootstraps */
for (phase = 0; phase < 2; phase++)
for (ptr = bootStraps.next; ptr != &bootStraps; ptr = ptr->next)
processBootStrap(ptr, bootPages, phase);
/* Place failsafe image anywhere sections */
if (failsafeImage)
processImage(failsafeImage, bootPages, imageDirectoryPages, 1, devices, target);
if (!bootPages->imageControlDirectoryPtr)
{
/*
* We can now set the base address for the image directory and image
* control structures in FLASH.
* We must find a suitable address after (before on the STb5301) any
* failsafe and bootstrap sections. We then rounded off to the nearest new
* FLASH block if the -bootsep option was specified and find the next space
* which is large enough to contain the image directory pages.
* We have to scan what exists in bootPages - recording what we did above is
* not enough as we need to take into account anything already in FLASH.
*/
unsigned int protectableWatermark =
#if defined(__mb390__) || defined(__mb424__) || defined(__mb435__)
(0x80000000 - sizeof(bootPages_t));
#else
FLASH_BASE + sizeof(bootPages_t);
#endif
int count;
buffer_t* buffer;
/* Search bootstrap descriptors */
for (count = 0; count < FLASH_MAX_CPUS; count++)
{
if (*((unsigned int*)&bootPages->bootStrapDescriptors[count]))
{
#if defined(__mb390__) || defined(__mb424__) || defined(__mb435__)
if (bootPages->bootStrapDescriptors[count].startAddress < protectableWatermark)
protectableWatermark = bootPages->bootStrapDescriptors[count].startAddress;
#else
if (bootPages->bootStrapDescriptors[count].startAddress +
bootPages->bootStrapDescriptors[count].length > protectableWatermark)
protectableWatermark = bootPages->bootStrapDescriptors[count].startAddress +
bootPages->bootStrapDescriptors[count].length;
#endif
}
}
/* Search failsafe image sections */
if (*((unsigned int*) &bootPages->failsafeImageControlStructure) != 0xFFFFFFFF)
{
imageControl_t* fsImg = &bootPages->failsafeImageControlStructure;
for (count = 0; count < fsImg->numSections; count++)
{
#if defined(__mb390__) || defined(__mb424__) || defined(__mb435__)
if (fsImg->sections[count].sourceAddress < protectableWatermark)
protectableWatermark = fsImg->sections[count].sourceAddress;
#else
if (fsImg->sections[count].sourceAddress +
fsImg->sections[count].length > protectableWatermark)
protectableWatermark = fsImg->sections[count].sourceAddress +
fsImg->sections[count].length;
#endif
}
}
/*
* Move on to next new FLASH block if we are separating boot and main
* application image FLASH blocks or there is a failsafe application.
*/
if (*((unsigned int*) &bootPages->failsafeImageControlStructure) != 0xFFFFFFFF ||
separateBootAndAppFlashBlocks)
{
int deviceIndex;
#if defined(__mb390__) || defined(__mb424__) || defined(__mb435__)
protectableWatermark = flashBlockBase(devices, protectableWatermark, &deviceIndex) -
sizeof(imageDirectoryPages_t);
#else
protectableWatermark = flashBlockBase(devices, protectableWatermark, &deviceIndex) +
flashBlockSize(devices[deviceIndex], protectableWatermark);
#endif
}
/* Use findBestFree to get to a space big enough (we may already be there) */
protectableWatermark = findBestFree(sizeof(imageDirectoryPages_t),
MIN_SECTION_ALIGNMENT, &flashMap,
protectableWatermark);
bootPages->imageControlDirectoryPtr = (unsigned int*)protectableWatermark;
/* Also reserve the space in the flashMap */
buffer = (buffer_t*)allocate(sizeof(buffer_t));
buffer->address = protectableWatermark;
buffer->length = sizeof(imageDirectoryPages_t);
buffer->info.type = MEM_USED;
updateMemMap(buffer, &flashMap);
}
if (*((unsigned int*) &bootPages->failsafeImageControlStructure) != 0xFFFFFFFF ||
separateBootAndAppFlashBlocks)
{
/*
* If there is a new or existing failsafe image ensure findBestFree will
* never return an address below the main application image control
* directory by setting the whole range as used in the flashMap.
*/
#if defined(__mb390__) || defined(__mb424__) || defined(__mb435__)
forceRangeInMemMap((unsigned int) bootPages->imageControlDirectoryPtr,
0x80000000 - (unsigned int)bootPages->imageControlDirectoryPtr,
#else
forceRangeInMemMap(FLASH_BASE, ((unsigned int)bootPages->imageControlDirectoryPtr) - FLASH_BASE,
#endif
MEM_USED, &flashMap);
}
/* Place remaining anywhere sections */
for (ptr = images.next; ptr != &images; ptr = ptr->next)
processImage(ptr, bootPages, imageDirectoryPages, 1, devices, target);
/*
* Process any specific requests to make given slots bootable.
*/
processMakeBoots(imageDirectoryPages);
/*
* Ensure at least one image per CPU is bootable.
*/
checkBootableImages(imageDirectoryPages);
printf("\n");
/*
* Prepare the image directory pages for placement in FLASH.
* This warps the RAM pointers to be FLASH pointers.
*/
romifyImageDir(boot
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -