📄 mkbinrom.pl
字号:
# This is a non-deflated section containing data or signature for a
# SigDMA. We update the relevant source address in the associated
# info section (already in the FLASH representation). We don't
# actually have to do this (and flasher wouldn't) as the source
# address can be worked out at run time (like imagesigdma.c does).
my $remainder = $secNum % 3;
if ($remainder == 1)
{
replaceBinaryInFlashFile("SigDMA data source address for SigDMA " .
(int($secNum / 3) + 1) . " in slot $slot",
$sectionInfo[$secNum - $remainder]->{srcAddr},
\pack('V', $sec->{srcAddr}));
}
else
{
replaceBinaryInFlashFile("SigDMA signature address for SigDMA " .
(int($secNum / 3) + 1) . " in slot $slot",
$sectionInfo[$secNum - $remainder]->{srcAddr} + 16,
\pack('V', $sec->{srcAddr}));
}
}
my $descStr;
if (($sec->{type} & $SECTION_TYPE_MASK) == $SECTION_TYPE_LX_BOOT)
{
$descStr = "ST200 .boot";
}
else
{
$descStr = "anywhere";
}
addBinaryToFlashFile("$descStr section in slot $slot for CPU $realCpuNum",
$sec->{srcAddr}, \$sec->{data});
# Update the source address to be an address rather than an offset from
# $FLASH_START now it has been stored
$sec->{srcAddr} += $FLASH_START;
# For an ST200 .boot section override the entry address.
if (($sec->{type} & $SECTION_TYPE_MASK) == $SECTION_TYPE_LX_BOOT)
{
my $endOfSecOffset = $sec->{srcAddr} +
$sec->{len} - $FLASH_START;
if ($endOfBootSectorFromFS < $endOfSecOffset)
{
$endOfBootSectorFromFS = $endOfSecOffset;
}
# If we're Cryptocore signing we also warn that the burnt ROM image
# will not be updatable as the .boot section has to be within the boot
# sector, but this means the boot sector now covers any failsafe
# application, the main application image directory and control
# structures and any sections placed before this one (all in-place
# sections and any anywhere sections from images processed before this
# one.
if ($cryptocoreSigning)
{
warn("Warning: The ROM image produced will not be updatable as the .boot " .
"section for the image in slot $slot must be in the signed boot " .
"sector, but it was placed above the main application image " .
"directory. It is recommended that you re-link your ST200 " .
"executable using a linker script which locates the .boot section " .
"within, and at the beginning of, the .text section such as the " .
"st200crypt.ld provided in the Cryptocore Support Package.\n");
}
$sec->{type} = $SECTION_TYPE_SKIP | $PLACEMENT_TYPE_INPLACE;
$entryAddr = $sec->{srcAddr};
}
}
# If this is a reserve section, record it in @reserveSecs
my $cteOffset = getCTEoffset($sec, 1);
if ($cteOffset != -1)
{
# Is a reserve section - add to @reserveSecs along with the slot it is
# in so we can identify which app it was from later
my $reserveSecInfo;
$reserveSecInfo->{slot} = $slot;
$reserveSecInfo->{secInfo} = $sec;
push(@reserveSecs, $reserveSecInfo);
print("Is a reserve section\n") if ($verboseOutput);
}
}
# Is this slot supposed to be bootable? A fail-safe image is always bootable.
if ($slot == -1 || scalar(grep($_ == $slot, @bootSlots)))
{
die("cannot make slot containing relocatable library bootable (slot $slot), stopped") if ($isRelocLib);
die("cannot make slot containing data bootable (slot $slot), stopped") if ($isDataImg);
$cpu |= $FLASH_BOOT_FLAG;
print("Made slot $slot bootable\n") if ($verboseOutput);
}
# Set the directory pointer if this is not a fail-safe image (slot -1)
if ($slot != -1)
{
replaceBinaryInFlashFile("IC directory ptr for slot $slot",
$mainICDoffset + ($slot * 4),
\pack("V", $FLASH_START + $icsMemOffset));
}
# Put the image control structure non-section info in position
my $descListRef = padList(32, [unpack("C32", $desc)]);
addBytesToFlashFile("ICS non-section info for slot $slot", $icsMemOffset,
[(@$descListRef, intToLittleEndBytes($cpu), intToLittleEndBytes($stackAddr),
intToLittleEndBytes($entryAddr), intToLittleEndBytes($numSec))]);
$icsMemOffset += 32 + 4 + 4 + 4 + 4;
# Put the section specific info into the image control structures
foreach my $sec (@sectionInfo)
{
# We use the section type mask on type field so placement type is removed
# in the ROM produced
my $type = $sec->{type} & $SECTION_TYPE_MASK;
addBinaryToFlashFile("ICS section info for slot $slot", $icsMemOffset,
\pack("VVVV", ($type, $sec->{srcAddr}, $sec->{dstAddr}, $sec->{len})));
$icsMemOffset += 4 + 4 + 4 + 4;
}
}
return $topOffset;
}
#
# This sub reads a complete binary ROM image into our representation of FLASH and
# tries to grab the boot sector size from it so it can sign it (only useful for
# Cryptocore systems).
# Note that we cannot sign any regions (only the boot sector) when signing a
# binary ROM image, so this is only useful if the Cryptocore i-monitors are not
# going to be enabled.
# Returns the boot sector size.
#
sub readBinROMToFlashFile($)
{
my $binFile = shift(@_);
my $binary = readBinFileToStr($binFile);
replaceBinaryInFlashFile("Binary from $binFile", 0, \$binary);
my $bootSecSize = 4 * unpack("V", substr($binary, $BOOT_GAP_LO - $FLASH_START - 4, 4));
if ($verboseOutput)
{
printf("Boot sector size at offset 0x%08x is %d bytes\n",
$BOOT_GAP_LO - $FLASH_START - 4, $bootSecSize);
}
return $bootSecSize;
}
#
# Sub called at the end of the program
#
sub closeDown()
{
# Close the FLASH file and remove all temporary files on exit
close(FLASHFILE);
unlinktmpfiles();
}
#
# Execution starts here
#
# Sort out the interrupt signal handler so we close down correctly
$SIG{INT} = sub { closeDown(); exit(1); };
# Get command line arguments/options
my @bootVectorImages = ();
my @sigDMAFiles = ();
my @bootstrapImages = ();
my $failSafeImage = undef;
my @applicationImages = ();
my $autoGenSigningKey = 0;
my $forceBootSectorSize = undef; # For forcing the Cryptocre boot sector size to a cmdline value
my $signingKeySigFile = undef;
while (@ARGV > 0)
{
my $arg = shift(@ARGV);
if ($arg =~ /^\-o$/)
{
# Get output ROM image filename
$outputROM = shift(@ARGV);
}
elsif ($arg =~ /\-flashbase$/)
{
# Get the FLASH base address to put in $FLASH_START (allows decimal, octal
# or hex)
$FLASH_START = shift(@ARGV);
$FLASH_START = oct($FLASH_START) if ($FLASH_START =~ /^0/);
}
elsif ($arg =~ /\-flashmap$/)
{
# Get the flash block map filename
$flashBlockMapFile = shift(@ARGV);
}
elsif ($arg =~ /\-setbssize$/)
{
# Get size to force boot sector size to
$forceBootSectorSize = shift(@ARGV);
$forceBootSectorSize = oct($forceBootSectorSize) if ($forceBootSectorSize =~ /^0/);
}
elsif ($arg =~ /\-signbinary$/)
{
# Get input binary ROM image filename
$inputBinaryROMFile = shift(@ARGV);
}
elsif ($arg =~ /^\-s$/)
{
# Get bootstrap image name
push(@bootstrapImages, shift(@ARGV));
}
elsif ($arg =~ /^\-v$/)
{
# Get boot vector image name
push(@bootVectorImages, shift(@ARGV));
}
elsif ($arg =~ /^\-i$/)
{
# Get application image name & slot if specified
push(@applicationImages, shift(@ARGV));
}
elsif ($arg =~ /^\-fs$/)
{
usage("may only specify one fail-safe image") if (defined($failSafeImage));
# Get fail-safe application image name
$failSafeImage = shift(@ARGV);
}
elsif ($arg =~ /^\-a$/)
{
# Get minimum section alignment (hex, oct, binary or decimal)
$MIN_SECTION_ALIGNMENT = shift(@ARGV);
$MIN_SECTION_ALIGNMENT = oct($MIN_SECTION_ALIGNMENT) if ($MIN_SECTION_ALIGNMENT =~ /^0/);
if ($MIN_SECTION_ALIGNMENT < 4 || $MIN_SECTION_ALIGNMENT % 4)
{
usage("alignment must be a positive multiple of word size ($MIN_SECTION_ALIGNMENT specified)");
}
}
elsif ($arg =~ /^\-b$/)
{
# Get slot number
my $slot = shift(@ARGV);
if ($slot < 0 || $slot > 63)
{
usage("slot to boot from must be in range 0 to 63");
}
push(@bootSlots, $slot);
}
elsif ($arg =~ /^\-d$/)
{
# We're getting either 1 or 2 filenames into the a single entry in the
# SigDMAFiles array
my @newEntry = (shift(@ARGV));
my $nextArg = $ARGV[0];
if (scalar(@ARGV) && $ARGV[0] !~ /^\-/)
{
# Didn't start with a "-", so interpret as another filename
push(@newEntry, shift(@ARGV));
}
push(@sigDMAFiles, \@newEntry);
}
elsif ($arg =~ /^\-k$/)
{
# Get signing key filename
$signingKeyFile = shift(@ARGV);
}
elsif ($arg =~ /^\-kauto$/)
{
$autoGenSigningKey = 1;
}
elsif ($arg =~ /^\-f$/)
{
# Get firmware key filename (Cryptocore 2)
$firmwareKeyFile = shift(@ARGV);
}
elsif ($arg =~ /^\-t$/)
{
# Get chip type
$chipType = shift(@ARGV);
}
elsif ($arg =~ /^\-sksig$/)
{
# Get signing key signature filename
$signingKeySigFile = shift(@ARGV);
}
elsif ($arg =~ /^\-stc$/)
{
# Get STC address as a number (takes hex, oct, binary or decimal)
$stcAddr = shift(@ARGV);
$stcAddr = oct($stcAddr) if ($stcAddr =~ /^0/);
die("STC address must be word aligned, stopped") if ($stcAddr % 4);
# Get STC value as a number (takes hex, oct, binary or decimal)
$stcValue = shift(@ARGV);
$stcValue = oct($stcValue) if ($stcValue =~ /^0/);
}
elsif ($arg =~ /^\-vcc$/)
{
# Get VCC address as a number (takes hex, oct, binary or decimal)
$vccAddr = shift(@ARGV);
$vccAddr = oct($vccAddr) if ($vccAddr =~ /^0/);
die("VCC address must be word aligned, stopped") if ($vccAddr % 4);
# Get VCC value as a number (takes hex, oct, binary or decimal)
$vccValue = shift(@ARGV);
$vccValue = oct($vccValue) if ($vccValue =~ /^0/);
}
elsif ($arg =~ /^\-V([0-9])?$/)
{
if (defined($1) && length($1) > 0)
{
$verboseOutput = $1;
}
else
{
$verboseOutput = 1;
}
}
else
{
usage("unrecognised option: $arg");
}
}
if ($outputROM eq "")
{
usage("must specify an output ROM image name");
}
if (defined($forceBootSectorSize))
{
# Check command line -setbssize argument is a valid size for a boot sector
if ($forceBootSectorSize % 64 || $forceBootSectorSize < 1)
{
usage("boot sector size must be a positive multiple of 64 bytes");
}
}
if ($inputBinaryROMFile ne "")
{
$inputFromBinaryROM = 1;
warn("Warning: When signing a binary ROM image, only the Cryptocore boot " .
"sector can be signed.\n");
if (@sigDMAFiles > 0)
{
usage("when signing a binary ROM image, cannot specify a SigDMA file");
}
if (@bootVectorImages > 0)
{
usage("when signing a binary ROM image, cannot specify a bootvector");
}
if (@bootstrapImages > 0)
{
usage("when signing a binary ROM image, cannot specify a bootstrap");
}
if (@applicationImages > 0)
{
usage("when signing a binary ROM image, cannot specify an application");
}
if (@bootSlots > 0)
{
usage("when signing a binary ROM image, bootable slots cannot be altered");
}
if ($FLASH_START != 0)
{
usage("when signing a binary ROM image, base address of FLASH cannot be altered");
}
}
else
{
if (@bootVectorImages < 1)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -