📄 mkbinrom.pl
字号:
{
die("$bootstrapFile does not contain a valid bootstrap, stopped");
}
# Extra sections may include a symbols and a relocations section which will
# be processed by this script.
my @sectionInfo = ();
# This is the code section...
$sectionInfo[0] = {type => $secType, srcAddr => $srcAddr, dstAddr => $dstAddr, len => $secLen};
# Now read the subsequent sections
my $symbolsSection;
my $relocationsSection;
for (my $count = 1; $count < $numSections; $count++)
{
my $readBuffer;
sysread(IN_FILE, $readBuffer, 16);
my @vals = unpack("VVVV", $readBuffer);
$sectionInfo[$count]{type} = $vals[0];
$sectionInfo[$count]{srcAddr} = $vals[1];
$sectionInfo[$count]{dstAddr} = $vals[2];
$sectionInfo[$count]{len} = $vals[3];
if (($vals[0] & $SECTION_TYPE_MASK) == $SECTION_TYPE_SYMBOLS)
{
$symbolsSection = $count;
}
elsif (($vals[0] & $SECTION_TYPE_MASK) == $SECTION_TYPE_RELOCATIONS)
{
$relocationsSection = $count;
}
}
# Retrieve the code and required info
my $code = "";
sysread(IN_FILE, $code, $secLen);
my $inROMAddr;
if (($secType & $PLACEMENT_TYPE_MASK) == $PLACEMENT_TYPE_INPLACE)
{
$inROMAddr = physMemAddr($srcAddr);
}
elsif (($secType & $PLACEMENT_TYPE_MASK) == $PLACEMENT_TYPE_ANYWHERE)
{
$inROMAddr = $FLASH_START + findSpaceInROMFor($secLen, $MIN_SECTION_ALIGNMENT, 1);
}
else
{
die("bootstrap in $bootstrapFile must be INPLACE or PIC, stopped");
}
# Read contents of further sections into @sectionInfo
for (my $count = 1; $count < $numSections; $count++)
{
if (sysread(IN_FILE, $sectionInfo[$count]{data}, $sectionInfo[$count]{len}) !=
$sectionInfo[$count]{len})
{
die("failed to read whole of section $count from $bootstrapFile ($!), stopped");
}
}
close(IN_FILE);
# Put bootstrap descriptor in our representation of FLASH
my $descListRef = padList(32, [unpack("C32", $desc)]);
replaceBytesInFlashFile("Bootstrap descriptor for CPU $realCpuNum ($desc)",
$FLASH_BOOTSTRAP_DESC_OFF + ($realCpuNum * 0x28),
[intToLittleEndBytes($inROMAddr),
intToLittleEndBytes($secLen), @$descListRef]);
# Put bootstrap code in FLASH representation
addBinaryToFlashFile("Bootstrap for CPU $realCpuNum ($desc)",
$inROMAddr - $FLASH_START, \$code);
# If boot sector doesn't cover the bootstrap, make it do so
if ($endOfBootSectorFromFS < ($inROMAddr - $FLASH_START + $secLen))
{
$endOfBootSectorFromFS = $inROMAddr - $FLASH_START + $secLen;
}
$topAddr = $inROMAddr - $FLASH_START + $secLen;
# Perform the relocations in the SYMBOLS and RELOCATIONS sections
if ($numSections > 1 && defined($symbolsSection) && defined($relocationsSection))
{
performRelocations($inROMAddr - $FLASH_START, \@sectionInfo, $cpuArchType,
$symbolsSection, $relocationsSection);
}
return $topAddr;
}
#
# Sub to process SigDMA files (binary/info, not a SigDMA image prepared by
# mkimage.pl). We will call mkimage.pl and create a single SigDMA image
# containing all SigDMAs on the mkbinrom.pl command line. We'll then update the
# list @applicationImages with it.
# Argument is a reference to an array of SigDMA arguments (one or 2 filenames)
# Returns the name of the image file created, which for now is always
# mkbinromsigdmas.img.
#
sub sigDMAsToImage($)
{
my $arrayRef = shift(@_);
my @sigDMAFiles = @$arrayRef;
my $outputSigDMAImageName = "mkbinromsigdmas.img";
return undef if (scalar(@sigDMAFiles) < 1);
# Construct the mkimage.pl command
my $cmdLine = $^X . " -w $PATH_TO_THIS_SCRIPT/mkimage.pl -o $outputSigDMAImageName -k $signingKeyFile";
$cmdLine .= " -V$verboseOutput" if ($verboseOutput);
for my $sigDMAFileArgArrayRef (@sigDMAFiles)
{
my @sigDMAFileArgs = @$sigDMAFileArgArrayRef;
$cmdLine .= " -sdma";
for my $file (@sigDMAFileArgs)
{
$cmdLine .= " $file";
}
}
print("Running command: $cmdLine\n") if ($verboseOutput > 1);
my $err = system($cmdLine);
if ($err)
{
warn("Warning: Failed to construct SigDMA image from files given via the -d option.\n");
}
else
{
print("Successfully created SigDMA image file $outputSigDMAImageName (this file will be re-generated - copy/rename it if you wish to preserve it)\n") if ($verboseOutput);
return $outputSigDMAImageName;
}
return undef;
}
#
# Populate the @slots array based on slots specified on the end of application
# names.
#
sub slotReservation($)
{
my $arrayRef = shift(@_);
for my $appImageFile (@$arrayRef)
{
if ($appImageFile =~ /^[^\@]+\@([0-9]+)/)
{
my $slot = $1;
if ($slot >= $FLASH_IMAGE_DIRECTORY_SIZE)
{
die("specified slot $slot in \"$appImageFile\" is out of range, stopped");
}
elsif (defined($slots[$slot]))
{
die("slot $slot already contains an image (when processing \"$appImageFile\"), stopped");
}
}
}
}
#
# Sub to process an application image file.
# Args: image name (and any extra parameters)
# 1 for fail-safe image, 0 for main image
# optional reference to a scalar which is to contain the top address used
# Returns the section info for this app.
#
sub processAppImage($$;$)
{
my $appImageFile = shift(@_);
my $failSafeImage = shift(@_);
my $topAddrRef = undef;
if (scalar(@_) > 0)
{
$topAddrRef = shift(@_);
$$topAddrRef = 0;
}
my $slot = -1; # Next free slot if left at -1 and not a fail-safe image
if (!$failSafeImage)
{
# See if there was a slot number after the filename (in @[0-63] notation)
if ($appImageFile =~ /\@([0-9]+)/)
{
# We've already checked the slot is available in slotReservation()
$slot = $1;
}
else
{
if ($appImageFile =~ /\@([^\:\%]+)/)
{
usage("invalid slot number '$1' in '$appImageFile'\n");
}
for (my $count = 0; $count < $FLASH_IMAGE_DIRECTORY_SIZE ;$count++)
{
unless (defined($slots[$count]))
{
$slot = $count;
last;
}
}
}
}
# If it's an ELF file, convert it to an image file and change $appImageFile accordingly
$appImageFile = convertIfElf("app", $appImageFile);
# Strip any extra stuff from the filename
$appImageFile =~ /^((?:[a-zA-Z]\:\\)?[^\@\:\%]+)/;
$appImageFile = $1;
# Read the header
my $appImageBuffer = "";
open(IN_FILE, $appImageFile) || die("failed to open application image file $appImageFile ($!), stopped");
binmode(IN_FILE);
sysread(IN_FILE, $appImageBuffer, $IMG_FILE_HEADER_LEN);
my ($magicNum, $desc, $cpuNum, $stackAddr, $entryAddr, $numSections, $secType, $srcAddr, $dstAddr, $secLen) =
readImgHeader($appImageBuffer, $appImageFile);
my $realCpuNum = $cpuNum & $CPU_NUMBER_MASK;
my $isApp = (($cpuNum & $IMAGE_TYPE_MASK) == 0);
if (!$failSafeImage)
{
# Register slot to CPU mapping
$slots[$slot] = $realCpuNum;
# Register we have an app image for this CPU
push(@cpusWithApps, $realCpuNum) if ($isApp && !scalar(grep($_ == $realCpuNum, @cpusWithApps)));
}
# We need to know where the sections from the app are going to go in ROM
# before we can write out the image control structure and the app sections...
# We have to ensure any INPLACE sections in ROM are allocated first and the
# remainder are put in the gaps left, so we only do INPLACE sections at this
# stage, and return the required information for non-INPLACE sections to be
# put out later.
# We've got the info on the first section - if there are more, their types,
# addresses and lengths will follow
my @sectionInfo = ();
$sectionInfo[0] = {type => $secType, srcAddr => $srcAddr, dstAddr => $dstAddr, len => $secLen};
for (my $count = 1; $count < $numSections; $count++)
{
sysread(IN_FILE, $appImageBuffer, 16);
my @vals = unpack("VVVV", $appImageBuffer);
$sectionInfo[$count]{type} = $vals[0];
$sectionInfo[$count]{srcAddr} = $vals[1];
$sectionInfo[$count]{dstAddr} = $vals[2];
$sectionInfo[$count]{len} = $vals[3];
}
my $haveReadSec;
for (my $count = 0; $count < $numSections; $count++)
{
$haveReadSec = 0;
if (($sectionInfo[$count]{type} & $PLACEMENT_TYPE_MASK) == $PLACEMENT_TYPE_NONE)
{
$sectionInfo[$count]{srcAddr} = 0; # Set the srcAddr to 0 as flasher.out would have
# Skip reading section
sysseek(IN_FILE, $sectionInfo[$count]{len}, 1);
$haveReadSec = 1;
}
elsif (($sectionInfo[$count]{type} & $PLACEMENT_TYPE_MASK) == $PLACEMENT_TYPE_ANYWHERE)
{
# We decide where to put these sections later
}
elsif (($sectionInfo[$count]{type} & $PLACEMENT_TYPE_MASK) == $PLACEMENT_TYPE_INPLACE)
{
# Ensure the address used is in physical memory
$sectionInfo[$count]{srcAddr} = physMemAddr($sectionInfo[$count]{srcAddr});
# We can put the section into our representation of FLASH now (script will exit with
# an error if it overlaps something already in place)
my $secData;
sysread(IN_FILE, $secData, $sectionInfo[$count]{len});
$haveReadSec = 1;
addBinaryToFlashFile("inplace section from $appImageFile",
$sectionInfo[$count]{srcAddr} - $FLASH_START,
\$secData);
# Update top address used if we need to
if (defined($topAddrRef) &&
$$topAddrRef < $sectionInfo[$count]{srcAddr} + $sectionInfo[$count]{len})
{
$$topAddrRef = $sectionInfo[$count]{srcAddr} + $sectionInfo[$count]{len};
}
# We store the data in $sectionInfo[$count][4] if this is the right size
# to be a reserve section (so we can check for the magic number to ensure
# it really is a reserve section)
if ($sectionInfo[$count]{len} == $RESERVE_1024_BIT_KEY ||
$sectionInfo[$count]{len} == $RESERVE_2048_BIT_KEY)
{
$sectionInfo[$count]{data} = $secData;
}
}
else
{
# Not a valid placement
die("$appImageFile has a section with invalid placement type, stopped");
}
if (!$haveReadSec)
{
# Get the code/data in sectionInfo too if we haven't processes it already,
# or discounted it as a section we need to store
sysread(IN_FILE, $sectionInfo[$count]{data}, $sectionInfo[$count]{len});
}
}
close(IN_FILE);
# Return the section info for this app
return [$slot, $desc, $cpuNum, $stackAddr, $entryAddr, $numSections, [@sectionInfo]];
}
#
# Sub to decide where to put anywhere sections and put them in our
# representation of FLASH, along with the image control directory and
# structures.
# Argument 1 is the offset from FLASH_START of the image control structures
# space to use (will be different for fail-safe versus main app images)
# 2nd argument is the offset from FLASH_START we can start placing sections at
# 3rd argument is a reference to an array of arrays of section info
# Returns top offset in FLASH used for section content.
#
sub doICSandAnywhereSecs($$$)
{
my $icsMemOffset = shift(@_);
my $secsOffset = shift(@_);
my $sectionsRef = shift(@_);
my $topOffset = 0;
# The information we need is in @$sectionsRef
foreach my $app (@$sectionsRef)
{
my $slot = $$app[0]; # -1 implies this is the fail-safe application
my $desc = $$app[1];
my $cpu = $$app[2];
my $realCpuNum = $cpu & $CPU_NUMBER_MASK;
my $stackAddr = $$app[3];
my $entryAddr = $$app[4];
my $numSec = $$app[5];
my $isRelocLib = (($cpu & $IMAGE_TYPE_MASK) == $IMAGE_TYPE_RELOC_LIB);
my $isDataImg = (($cpu & $IMAGE_TYPE_MASK) == $IMAGE_TYPE_DATA);
my $isSigDMAImage = (($cpu & $IMAGE_TYPE_MASK) == $IMAGE_TYPE_CC_SIGDMA);
# First find somewhere in ROM for each section, and put them in position
my $sectionInfoRef = $$app[6];
my @sectionInfo = @$sectionInfoRef;
for (my $secNum = 0; $secNum < scalar(@sectionInfo); $secNum++)
{
my $sec = $sectionInfo[$secNum]; # The current section being processed
if (($sec->{type} & $PLACEMENT_TYPE_MASK) == $PLACEMENT_TYPE_ANYWHERE)
{
# Find a space in ROM big enough
$sec->{srcAddr} = findSpaceInROMFor($sec->{len}, $MIN_SECTION_ALIGNMENT,
0, $secsOffset);
if ($topOffset < $sec->{srcAddr} + $sec->{len})
{
$topOffset = $sec->{srcAddr} + $sec->{len};
}
if ($isSigDMAImage && ($secNum % 3) != 0 &&
($sec->{type} & $SECTION_TYPE_MASK) != $SECTION_TYPE_DEFLATED)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -