📄 flasher.c
字号:
* Reduce the size of the list buffer, and slide it up.
* Then insert the new buffer before it.
*/
ptr->address += buffer->length;
ptr->length -= buffer->length;
insertBefore(buffer, ptr);
break;
}
}
else if ((ptr->address + ptr->length) == (buffer->address + buffer->length))
{
/*
* The end addresses match, so we need to shrink the list buffer, and
* insert the new buffer after it.
*/
ptr->length -= buffer->length;
insertBefore(buffer, ptr->next);
break;
}
else
{
/*
* The new buffer is in the middle of the list buffer.
* We need to shrink the list buffer, then insert the new buffer after
* it, and finally create another new buffer to go at the very end to
* account for the residue of the original list buffer.
*/
buffer_t* newBuffer = (buffer_t*)allocate(sizeof(buffer_t));
newBuffer->address = buffer->address + buffer->length;
newBuffer->length = (ptr->address + ptr->length) - newBuffer->address;
newBuffer->info.type = ptr->info.type;
ptr->length = (buffer->address - ptr->address);
insertBefore(buffer, ptr->next);
insertBefore(newBuffer, buffer->next);
break;
}
}
else if ((ptr->address > buffer->address) && ((ptr->address + ptr->length) >= buffer->address))
{
fprintf(stderr, "flasher: Memory @ 0x%08x cannot be %s\n", buffer->address,
otherType == MEM_FREE ? "allocated" : "freed");
exit(1);
}
}
/* Coalesce adjacent regions of same type */
coalesceMemMap(memRoot);
}
/*
* Routine to find the best free block for this request.
* Best is defined as the smallest which can satisfy.
* The alignment parameter specifies on what boundary the memory must start
* (e.g. 64 == on a 64 byte boundary).
* stopAtIfMatch forces the search to finish early if a match has been found by
* the address given (ignored if 0).
*/
static unsigned int findBestFree(unsigned int length, unsigned int alignment, buffer_t* memRoot, unsigned int stopAtIfMatch)
{
buffer_t* best = NULL;
unsigned int bestDiff = 0;
buffer_t* ptr;
#if defined(__mb390__) || defined(__mb424__) || defined(__mb435__)
for (ptr = memRoot->prev; ptr != memRoot; ptr = ptr->prev)
{
if (ptr->info.type == MEM_FREE && ptr->length >= length)
{
unsigned int diff = (ptr->length - length) - ((ptr->address + ptr->length - length) & (alignment - 1));
if (stopAtIfMatch && ptr->address + diff <= stopAtIfMatch && best)
break;
/* If an aligned version of stopAtIfMatch is within this free region and
is lower than what diff would currently give us, use it instead.
*/
if (stopAtIfMatch && (stopAtIfMatch & ~(alignment - 1)) < ptr->address + diff &&
stopAtIfMatch > ptr->address)
diff = (stopAtIfMatch & ~(alignment - 1)) - ptr->address;
#else /* Not an STb5301 */
for (ptr = memRoot->next; ptr != memRoot; ptr = ptr->next)
{
if (ptr->info.type == MEM_FREE && ptr->length >= length)
{
unsigned int diff = (alignment - (ptr->address & (alignment - 1))) & (alignment - 1);
if (stopAtIfMatch && ptr->address + diff >= stopAtIfMatch && best)
break;
/* If an aligned version of stopAtIfMatch is within this free region and
is higher than what diff would currently give us, use it instead.
*/
if (stopAtIfMatch && (stopAtIfMatch & ~(alignment - 1)) > ptr->address + diff &&
stopAtIfMatch && (stopAtIfMatch & ~(alignment - 1)) + length < ptr->address + ptr->length)
diff = (stopAtIfMatch & ~(alignment - 1)) - ptr->address;
#endif
if (ptr->length - diff >= length)
{
if (best == NULL)
{
best = ptr;
bestDiff = diff;
}
else
{
if (ptr->length < best->length)
{
best = ptr;
bestDiff = diff;
}
}
}
}
}
if (best == NULL)
{
fprintf(stderr, "flasher: Insufficient space in FLASH\n");
exit(1);
}
return best->address + bestDiff;
}
/*
* Routine to initialise the FLASH memory map. This is used when placing user
* images into the FLASH.
*/
static void createMemoryMap(bootPages_t* bootPages, imageDirectoryPages_t* imageDirectoryPages, unsigned int flashSize)
{
buffer_t* buffer;
int i;
/*
* Initial state - boot pages & image dir pages (if valid) allocated, all the
* rest is free.
*/
buffer = (buffer_t*)allocate(sizeof(buffer_t));
buffer->address = FLASH_START;
buffer->length = flashSize;
buffer->info.type = MEM_FREE;
addBuffer(buffer, &flashMap);
/*
* Factor in the FLASH allocated to bootstrap sections.
*/
for (i = 0; i < FLASH_MAX_CPUS; i++)
{
bootStrapDescriptor_t* desc;
desc = &bootPages->bootStrapDescriptors[i];
if (desc->startAddress && desc->length)
{
buffer = (buffer_t*)allocate(sizeof(buffer_t));
buffer->address = (unsigned int)desc->startAddress;
buffer->length = desc->length;
buffer->info.type = MEM_USED;
updateMemMap(buffer, &flashMap);
}
}
/*
* Set the bootPages as used in the flash map.
*/
buffer = (buffer_t*)allocate(sizeof(buffer_t));
#if defined(__mb390__) || defined(__mb424__) || defined(__mb435__)
buffer->address = 0x80000000 - sizeof(bootPages_t);
#else
buffer->address = FLASH_BASE;
#endif
buffer->length = sizeof(bootPages_t);
buffer->info.type = MEM_USED;
updateMemMap(buffer, &flashMap);
/*
* If we have an image directory pointer in the bootPages, use it to set the
* image directory and control space as used in the flash map.
*/
if (bootPages->imageControlDirectoryPtr)
{
buffer = (buffer_t*)allocate(sizeof(buffer_t));
buffer->address = (unsigned int)bootPages->imageControlDirectoryPtr;
buffer->length = sizeof(imageDirectoryPages_t);
buffer->info.type = MEM_USED;
updateMemMap(buffer, &flashMap);
}
/*
* Create a free region in the control map for image control structures.
*/
buffer = (buffer_t*)allocate(sizeof(buffer_t));
buffer->address = (unsigned int)&imageDirectoryPages->imageControlSpace;
buffer->length = sizeof(imageDirectoryPages->imageControlSpace);
buffer->info.type = MEM_FREE;
addBuffer(buffer, &controlMap);
/*
* Factor in the FLASH allocated for user images.
* Don't forget to do any fail-safe image that might be in place (-1).
*/
for (i = -1; i < FLASH_IMAGE_DIRECTORY_SIZE; i++)
{
imageControl_t* entry;
if (i >= 0)
entry = imageDirectoryPages->directory.entries[i];
else
entry = &bootPages->failsafeImageControlStructure;
if ((i == -1 && *((unsigned int*)&bootPages->failsafeImageControlStructure) != 0xFFFFFFFF) ||
(i != -1 && entry))
{
imageSection_t* sections = entry->sections;
buffer_t* buffer;
int j;
for (j = 0; j < entry->numSections; j++)
{
if (sections[j].type != SECTION_TYPE_ZERO)
{
buffer = (buffer_t*)allocate(sizeof(buffer_t));
buffer->address = sections[j].sourceAddress;
buffer->length = sections[j].length;
buffer->info.type = MEM_USED;
updateMemMap(buffer, &flashMap);
}
}
if (i >= 0)
{
buffer = (buffer_t*)allocate(sizeof(buffer_t));
buffer->address = (unsigned int)entry;
buffer->length = sizeof(imageControl_t) + (entry->numSections - 1) * sizeof(imageSection_t);
buffer->info.type = MEM_USED;
updateMemMap(buffer, &controlMap);
}
}
}
}
/*
* Routine to create a RAM version of the image directory, based on the version
* found in FLASH. The pointers from the FLASH version are warped into RAM
* pointers.
*/
static void makeNewImageDir(bootPages_t* bootPages, imageDirectoryPages_t* newPages, imageDirectoryPages_t* romPages)
{
int i;
*newPages = *romPages;
for (i = 0; i < FLASH_IMAGE_DIRECTORY_SIZE; i++)
{
imageControl_t* entry;
entry = (imageControl_t*)newPages->directory.entries[i];
if (entry)
{
newPages->directory.entries[i] =
(imageControl_t*)(((unsigned int)entry - (unsigned int)bootPages->imageControlDirectoryPtr) +
(unsigned int)newPages);
}
}
}
/*
* Routine to morph a RAM based image directory into a FLASH one (we morph the
* pointers in the image dir to be FLASH pointers).
*/
static void romifyImageDir(bootPages_t* bootPages, imageDirectoryPages_t* newPages)
{
int i;
for (i = 0; i < FLASH_IMAGE_DIRECTORY_SIZE; i++)
{
imageControl_t* entry;
entry = newPages->directory.entries[i];
if (entry)
{
newPages->directory.entries[i] =
(imageControl_t*)((unsigned int)entry - (unsigned int)newPages +
(unsigned int)bootPages->imageControlDirectoryPtr);
}
}
}
/*
* Routine to report command usage and abort.
*/
static void usage(const char* msg)
{
fprintf(stderr, "flasher: %s\n"
"Usage: flasher [-t <target board>]\n"
" [-p <binary or hex image>[@<binary_base_address>]] |\n"
" [-r <binary image>] |\n"
" [[-v <bootvector image> [-v...]]\n"
" [-s <bootstrap image> [-s...]]\n"
" [-fs <fail-safe image>]\n"
" [-i <application image>[@<slot>] [-i...]]\n"
" [-d <slot> [-d ...]]\n"
" [-b <slot>]\n"
" [-bootsep]]\n"
" [-f <option file>]\n"
" [-e]\n\n"
"<slot> must be in the range 0..63\n\n"
"-v <imgfile> : install image as a CPU boot vector\n"
"-s <imgfile> : install image as a CPU boot strap\n"
"-fs <imgfile>: install image as the fail-safe image\n"
"-i <imgfile> : install image as an application image\n"
"-d <slot> : delete the image in slot\n"
"-b <slot> : make the image in slot a boot image\n"
"-bootsep : separate FLASH blocks containing boot code and application code so they\n"
" can be protected\n"
"-p <binfile> : program with raw binary image (or ST20-style hex file if .hex extension)\n"
"-r <binfile> : dump all FLASH to binary image\n"
"-f <optfile> : read options from file\n"
"-e : erase the FLASH\n"
"-t <board> : override default target board ("DEFAULTPLATFORM")\n"
" %s\n",
msg, flashGetTargetNames());
exit(1);
}
/*
* Routine to make the given slot the boot slot for that CPU.
* No other slot for that CPU will be marked as bootable.
*/
static void makeBootable(imageDirectoryPages_t* imageDirectoryPages, int slot)
{
unsigned int cpu;
imageControl_t* controlStruct;
int i;
controlStruct = imageDirectoryPages->directory.entries[slot];
if (!controlStruct)
{
fprintf(stderr, "flasher: Slot %d is empty\n", slot);
exit(1);
}
cpu = controlStruct->CPU & FLASH_CPU_MASK;
controlStruct->CPU |= FLASH_BOOT_FLAG;
printf("Set image '%s' in slot %d to be a boot image\n", controlStruct->description, slot);
for (i = 0; i < FLASH_IMAGE_DIRECTORY_SIZE; i++)
{
if (i != slot)
{
controlStruct = imageDirectoryPages->directory.entries[i];
if (controlStruct && ((controlStruct->CPU & FLASH_CPU_MASK) == cpu))
{
controlStruct->CPU &= (~FLASH_BOOT_FLAG);
}
}
}
}
#ifndef SFXIMAGENAME
/*
* Routine used when parsing the command line to extract an address.
*/
static int getAddress(char* ptr)
{
unsigned int addr;
char* endp;
addr = strtoul(ptr, &endp, 0);
if (endp == ptr)
{
usage("Failed to parse address");
}
return addr;
}
/*
* Routine used when parsing the command line to extract a slot number.
*/
static int getSlot(char* ptr)
{
int slot;
char* endp;
slot = strtol(ptr, &endp, 10);
if (endp == ptr)
{
usage("Failed to parse slot number");
}
if ((slot < -1) || (slot >= FLASH_IMAGE_DIRECTORY_SIZE))
{
usage("Invalid slot number specified");
}
return slot;
}
/*
* Read command line arguments from file.
*/
static char** inputOptionFile(const char* fileName, int* argc)
{
FILE* fp;
size_t fileSize;
char* s, *buffer;
char** argv = NULL;
*argc = 0;
/*
* Open up the command file.
*/
if (!(fp = fopen(fileName, "r")))
{
fprintf(stderr, "flasher: Failed to open %s\n", fileName);
exit(1);
}
/*
* Allocate enough space for entire file.
*/
fseek(fp, 0, SEEK_END); /* End of file */
fileSize = ftell(fp);
fseek(fp, 0, SEEK_SET); /* Beginning of file */
buffer = allocate(fileSize + 1);
/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -