📄 mkimage.pl
字号:
: # Perl
eval 'exec perl -w -S $0 ${1+"$@"}'
if 0;
#
# mkimage.pl
#
# Copyright (c) 2003-2007 STMicroelectronics Limited. All rights reserved.
#
# A perl script to build an image file from an executable file.
#
# The input files can be ELF, ST-Hex, or Motorola SRec format.
#
# ELF files from the ST40 and ST200 toolchains are supported.
# ST-Hex and Motorola SRec files from the ST20 toolchain are also supported.
#
# Syntax and usage notes
# ======================
#
# perl -w mkimage.pl <options>
#
# Syntax can be seen by running the script with no options.
#
#
# Image files (*.img) are the output of this program, and the input files
# for flasher.out or mksignedrom.pl.
#
# The format of an image file is as follows:
#
# Start Offset End offset Description
# -------------------------------------------------------------
# 0x00000000 0x00000003 Magic number (0x13a9f17e)
# 0x00000004 0x00000023 ASCIIZ description
# 0x00000024 0x00000027 CPU number (0-7). Arch type and reloc lib bit also ORed in
# 0x00000028 0x0000002B Stack address (if applicable)
# 0x0000002C 0x0000002F Entry point
# 0x00000030 0x00000033 Number of sections following (N)
# 0x00000034... Section descriptors
# 0x00000034+(N*0x10)... Concatenated section data
#
# The CPU number field decomposes to:
# 0x000R0A0N
# where R is 1 if the image is a relocatable library (not to be touched by the
# bootstrap), A is the CPU architecture (ST40 = 1, ST200 = 2, ST20 = 3) and N is
# the CPU number.
#
# A section descriptor looks like this:
#
# 0x00000000 0x00000003 Type
# 0x00000004 0x00000007 Source address
# 0x00000008 0x0000000B Destination address
# 0x0000000C 0x0000000F Length
#
# The section type is encoded as follows:
#
# 0xN000000n
#
# where N is the placement hint and n is the boot time copy strategy.
#
# N - 0 ==> place anywhere
# 1 ==> has no placement requirement (not held in ROM at all)
# 2 ==> place precisely at its source address in ROM, and init to 0xff
# 3 ==> place precisely at its source address in ROM
#
# n - 0 ==> do nothing with this section
# 1 ==> copy this section from its source address to its dest address
# 2 ==> zero this section at its dest address
# 3 ==> runlength decode this section
# 4 ==> inflate this section
# 5 ==> ELF symbol table section (for files with relocations)
# 6 ==> ELF relocations section
# 7 ==> ST200 Toolset .boot section
#
#
# NOTE - runlength encoding is not currently supported by this script
#
# If the addresses in ELF files look like ST40 addresses, they are
# left as such. Otherwise they are mapped to ST40 P2 addresses.
#
require 5.006_001;
use strict;
use warnings;
use Getopt::Std;
use File::Basename;
use File::Copy;
# The Compress::Zlib module is not in all perl distributions - we jump through
# a few hoops so that those who do not need compression can use this script on
# a perl distribution without the Compress::Zlib module.
BEGIN
{
eval { require Compress::Zlib; };
import Compress::Zlib;
}
BEGIN
{
# Include subs used by mkimage.pl and mkbinrom.pl
my ($null, $PATH_TO_THIS_SCRIPT, $null2) = fileparse($0, "\\..*");
unshift(@INC, $PATH_TO_THIS_SCRIPT);
}
use mkcommon;
# Extract script name and path to script for later use
our ($script_bname, $PATH_TO_THIS_SCRIPT, $script_ext) = fileparse($0, "\\..*");
our $THIS_SCRIPT = $script_bname . $script_ext;
my %options = ();
my $architecture = undef;
my $startAddress = undef;
# Cryptocore values
my $CRYPTOCORE_VERSION = 1.5; # 1.5 and 2.0 are supported
my $CTE_SIGNING_LEVEL = 4; # Signing levels for the config table entry
# fields: 1 - just signed block len
# 2 - block addr and len
# 3 - block len, sig addr & block num
# 4 - block addr & len, sig addr & block num
our $SIGGEN_TOOL = "siggen";
if ($^O =~ /win/i)
{
$SIGGEN_TOOL .= ".exe";
}
my $CHIP_INFO_FILE = $PATH_TO_THIS_SCRIPT . "chipinfo.ini";
my $MAX_SIGNED_BLOCKS = 8;
my $MAX_SIGNED_BLOCK_LEN = 64*1024*1024/4; # In words
my $lenDigitalSignature = 128; # In bytes (will be doubled if using 2048 bit keys)
my $ALLOW_SIGNATURE_DEFLATION = 0; # Signature deflation is disabled (they don't get smaller anyway!)
my $vccAddr = undef; # VCC address
my $vccValue = undef; # VCC value
my $stcAddr = undef; # STC address
my $stcValue = undef; # STC value
my $regionsInFlash = undef; # Usually based on whether the default
# section placement is 'inplace', but
# setting this will override that
my @cc2CPUEnables = (); # List of CPUs to set as enabled when
# Cryptocore 2 signing. If empty will
# enable the CPU specified by -c
my @sigDMAFiles = (); # List of array references which
# contain SigDMA file names (1 or 2
# depending on whether binary used)
my $signedSomething = 0; # Becomes 1 if some signing is done
# for an application ELF file
# Used as start addresses for Cryptocore signed blocks if needed
my $textSectionDst;
my $rodataSectionDst;
# Place to throw things away to
my $null;
#
# Sub to report correct usage
#
sub usage($)
{
print("\n$THIS_SCRIPT: ", shift(@_), "\n\n");
print("usage: perl $THIS_SCRIPT -o <output_image_file>\n",
" -b file[\@address]\n",
" -c <cpu_number>\n",
" -d \"description\"\n",
" -e <elf_file>\n",
" [-j \"section(s)\"]\n",
" [-p copy | -p pic | -p inplace | -p deflate]\n",
" -h <hex_file>\n",
" -r <relocatable_elf_file>\n",
" [-p copy | -p deflate]\n",
" -s <srec_file>\n",
" -z address,size\n",
" -V[n]\n",
" (the following are only useful on Cryptocore parts)\n",
" -ce [0-3]\n",
" -g [0-" . ($MAX_SIGNED_BLOCKS - 1) . "]\n",
" -[not]inflash\n",
" -k <signing_key_file>\n",
" -sdma <binary_sigdma_file> <sigdma_info_file>\n",
" -sdma <sigdma_info_file>\n",
" -t chip_type\n",
" -stc <stc_addr> <stc_value>\n",
" -vcc <vcc_addr> <vcc_value>\n\n",
" where:\n",
" -o specifies an output image file\n",
" -b specifies a binary data input file and an optional 'inplace' address\n",
" -c specifies the CPU the image is for (0..7)\n",
" -d specifies a description of the image\n",
" -e specifies an ST40 or ST200 ELF input file\n",
" -h specifies an ST20 hex input file\n",
" -r specifies an ST40 or ST200 relocatable ELF input file\n",
" -s specifies an ST20 srec input file\n",
" -z specifies location and size of a blank section\n",
" -V[n] specifies verbose mode (verbosity level n)\n",
" With -e the following options also apply:\n",
" -j specifies which sections to take (defaults to all)\n",
" -p species how to process the ELF image:\n",
" -p copy (default) sections are copied from ROM to RAM\n",
" -p pic sections to be placed anywhere in ROM, and run in situ\n",
" -p inplace sections to be placed in ROM where they are linked for\n",
" -p deflate compressed sections to be decompressed from ROM to RAM\n",
" With -r the following options also apply:\n",
" -p species how to process the ELF image:\n",
" -p copy (default) sections are copied from ROM to RAM\n",
" -p deflate compressed sections to be decompressed from ROM to RAM\n",
" (the following are only useful on Cryptocore parts)\n",
" -ce specifies a Cryptocore 2 i-monitor CPU enable to set (0..3). Use\n",
" multiple times to set for multiple CPUs. If not used, the enable\n",
" for the CPU specified by the -c option will be set\n",
" -g specifies the block number of the first signed block from the ELF image\n",
" -[not]inflash specifies whether signed blocks should be marked as being in FLASH\n",
" or not (Cryptocore 2). This overrides the default which is to mark\n",
" as in FLASH only if the default section type is 'inplace'\n",
" -k specifies a signing key file to sign with\n",
" -sdma specifies SigDMA files, which can be either a binary data file for the\n",
" SigDMA data, followed by a SigDMA info file, or just a SigDMA info file\n",
" which contains both info and data (Cryptocore 2)\n",
" Note: Multiple SigDMAs can be put in a single image file if useful\n",
" -t specifies a chip type (used with $CHIP_INFO_FILE to look up boot sector gap addresses, etc.)\n",
" -stc specifies a Sales Type Check address and value (Cryptocore 2)\n",
" -vcc specifies a Version Control Check address and value (Cryptocore 2)\n");
exit(1);
}
sub translate5528($)
{
my $rawAddress = shift;
if (($rawAddress & 0xf0000000) != 0x40000000)
{
die("$rawAddress does not look like a valid ST20 address, stopped");
}
return ($rawAddress & 0x1FFFFFFF);
}
#
# Routine to filter the list of ELF sections going into the image
# file, by referencing the list of allowed sections given with the
# -j option (if any).
#
sub elfSectionAllowed($)
{
my $name = shift;
if (exists($options{j}))
{
for my $i (split(/ /,$options{j}))
{
if ($i eq $name)
{
return 1;
}
}
return 0;
}
return 1;
}
#
# Routine to create a list of the sections we need to consider
# in an ELF file.
# We do not care about the stack sections.
# This list of other sections is generated, and sections are
# coalesced if they are within 128 bytes of each other when
# loaded. Sections named .post_text_reserve or
# _post_rodata_reserve are forced to be of copy type even if
# the default is deflate type, as these are required to be
# uncompressed even it the text/read-only data is compressed.
# These must also not be coalesced, as we will recognise them
# later by their size, type and content (the name is not stored
# in '.img' files).
#
# Takes two parameters - the name of the ELF file, and
# the default section type to use.
#
sub getElfSections($$)
{
my $elfName = shift;
my $dumpCmd = getObjdump() . " -h ".$elfName;
my $defaultType = shift;
my @sections = ();
my @coalescedSections = ();
my $bootAddr = 0;
my $type;
my $size;
my $name;
my $dstAddr;
my $srcAddr;
my $bootStart;
open(HANDLE, $dumpCmd."|") or die("unable to open pipe ($!), stopped");
while (<HANDLE>)
{
if (/^ +[0-9]+ (\.\S+) +(\S+) +(\S+) +(\S+).*$/)
{
$name = $1;
$size = hex($2);
$dstAddr = hex($3);
$srcAddr = hex($4);
if ($name =~ /^\.text$/)
{
$textSectionDst = $dstAddr;
}
elsif ($name =~ /^\.rodata$/)
{
$rodataSectionDst = $dstAddr;
}
}
elsif (/^.+ LOAD.*$/ || (/^.+ (CONTENTS|ALLOC).*$/ && $name =~ /^\.post_(text|rodata)_reserve/))
{
#
# We force .post_(text|rodata)_reserve sections to be recognised.
#
# If the VMA & LMA addresses are the same, refer to the
# default section type, other wise we know for sure that
# this is a copy (or deflate) section.
#
# Filter out empty sections, and the stack while we are at it
#
if (($name ne ".stack") && ($size != 0))
{
if ($srcAddr == $dstAddr)
{
if ($name =~ /^\.post_(text|rodata)_reserve$/)
{
# Reserve sections cannot be deflate, and we warn if they are PIC
if ($defaultType == $defaultSectionTypes{"pic"})
{
$type = $defaultType;
warn("Warning: Creating PIC sections for Cryptocore image - " .
"protection unlikely to work.\n");
}
elsif ($defaultType == $defaultSectionTypes{"deflate"})
{
$type = $defaultSectionTypes{"copy"};
}
}
elsif ($name eq ".dynsym")
{
$type = $SECTION_TYPE_SYMBOLS;
}
elsif ($name =~ /\.rela\.*/)
{
$type = $SECTION_TYPE_RELOCATIONS;
}
elsif ($name =~ /^\.boot_reset$/)
{
# * Disregard .boot_reset sections
next;
}
else
{
$type = $defaultType;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -