⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mkbinrom.pl

📁 采用ST20 CPU的机顶盒的烧写程序
💻 PL
📖 第 1 页 / 共 5 页
字号:
: # Perl
eval 'exec perl -w -S $0 ${1+"$@"}'
    if 0;
#
# mkbinrom.pl
#
# Copyright (c) STMicroelectronics 2004-2007. All rights reserved.
#
# A perl script to build a ROM image from provided .img/elf files.
#
# It will also not work for the STb5301, which has the same memory map as the
# STi5100, an ST20-C2 part (boots from the top of FLASH).
#
# Syntax and usage notes
# ======================
#
# perl -w mkbinrom.pl <options>
#
# Syntax can be seen by running the script with no options.
#
#
# Multiple bootstraps and vectors can be provided as long as they have been
# prepared for different CPU's (done at the mkimage.pl stage or with extra
# ELF file input options).
#
# We don't know the size of the FLASH for the chip, so we will put images in
# FLASH sequentially from the base of FLASH after the boot and image directory
# information, the boot sector gap and the variable part of the boot sector.
# 

# NOTE: Assumption has been made that the fixed part of the boot sector will
# cover the entire prescribed FLASH layout ($FLASH_START to $FLASH_START + 
# 0x4000 = 16KB).  If this is not the case the layout below will need to be
# changed.

#
# The layout of the FLASH is as follows (as offsets from $FLASH_START):
#
#  0x00000000 - 0x0000003F  Boot vector for CPU 0
#  0x00000040 - 0x0000007F  Boot vector for CPU 1
#  ...
#  0x000001C0 - 0x000001FF  Boot vector for CPU 7
#  0x00000200 - 0x0000021F  ASCIIZ description for bootvector 0
#  0x00000220 - 0x0000023F  ASCIIZ description for bootvector 1
#  ...
#  0x000002E0 - 0x000002FF  ASCIIZ description for bootvector 7
#  0x00000300 - 0x0000043F  Bootstrap descriptors for CPUs 0 - 7 (see below)
#  0x00000440 - 0x00000443  Pointer to image control directory (main app)
#  0x00000444 - 0x0000053B  Image control strucutres for fail-safe app
#  0x0000053C - 0x0000053F  CRC for 0x00000000-0x0000053B
#  0x00000540 - X           Space required for bootstraps and fail-safe app sections
#  X          - Y           Padding to end of highest used FLASH block (anything
#                           below Y is to be considered non-updatable).  Note
#                           that if there is no fail-safe application there may
#                           be no padding.
#  Y          - Y + 0xFF    Main image control directory
#  Y + 0x100  - Y + 0x37FB  Main image control structures
#  Y + 0x37FC - Y + 0x3800  CRC for Y to Y + 0x37FB
#  
# References to the BOOT_GAP, boot sector, config_table and signatures are for
# Cryptocore signing and will be unused when not Cryptocore signing.
#
# The format of a bootstrap descriptor is:
#
#    0x0000 - 0x0003 Entry point
#    0x0004 - 0x0007 Size of bootstrap
#    0x0008 - 0x0027 ASCIIZ description
#
# The image control directory consists of 64 pointers to image control
# structures. These are the image slot descriptions. Unused entries are NULL.
#
# The format of an image control structure is:
#
#    0x0000 - 0x001F ASCIIZ description
#    0x0020 - 0x0023 CPU number (0-7). Top bit set if boot image. Arch and image types also ORed in.
#    0x0024 - 0x0027 Stack address
#    0x0028 - 0x002B Entry point
#    0x002C - 0x002F Number of sections which follow
#    0x0030+N*0x10 - 0x0033+N*0x10 Type (copy, zeroed, etc)
#    0x0034+N*0x10 - 0x0037+N*0x10 source address in FLASH
#    0x0038+N*0x10 - 0x003B+N*0x10 destination address in RAM
#    0x003C+N*0x10 - 0x003F+N*0x10 length in bytes (of source)
#

require 5.006_001;

use strict;
use warnings;

use Config;
use Getopt::Std;
use File::Basename;
use File::Copy;

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;
# The $useST40Addressing variable imported from mkcommon.pm should be set based
# on the architecture of the boot vector image put in for CPU 0 which would
# normally be the CPU to do the move from ROM to RAM (which is what we mean by
# master in this case).

# 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;

#
# Global and file scope constants/variables
#
my $ELF_MAGIC_NUMBER                 = 0x7F454C46;
our $FLASH_MAX_CPUS                  = 8;
my $FLASH_DESC_LEN                   = 32;
my $FLASH_BOOT_VECTOR_SIZE           = 64;
my $FLASH_IMAGE_DIRECTORY_SIZE       = 64;
my $FLASH_START                      = 0x00000000; # -flashbase overrides
my $FLASH_BOOTVEC_DESC_OFF           = 0x200;
my $FLASH_BOOTSTRAP_DESC_OFF         = 0x300;
my $FLASH_MAIN_ICD_PTR_OFFSET        = 0x440;
my $FLASH_MAIN_SECS_FROM_ICD         = 0x3800; # Length from main image control directory to where we can put sections
my $FLASH_FAILSAFE_ICS_OFFSET        = 0x444;
my $FLASH_PROTECTED_SECTIONS_OFFSET  = 0x540;
my $MIN_SECTION_ALIGNMENT            = 64; # Alignment for sections (can be overridden)

# Polynomial value used for CRCs
my $CRC_POLY                         = 0x04C14BD7;

# Cryptocore gap layout
my $BOOT_GAP_LO                      = undef;
my $BOOT_GAP_HI                      = 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_BLOCK_LEN             = 64*1024*1024/4; # In words
my $lenDigitalSignature              = 128; # In bytes (will be doubled if using 2048 bit keys)
my $vccAddr                          = undef; # VCC address
my $vccValue                         = undef; # VCC value
my $stcAddr                          = undef; # STC address
my $stcValue                         = undef; # STC value

# End of boot sector from FLASH start
my $endOfBootSectorFromFS            = 0;

# For cmdline args
my $outputROM                        = "";
my $signingKeyFile                   = "";
my $firmwareKeyFile                  = ""; # Cryptocore 2 only (signs the public modulus of the signing key)
my $chipType                         = "";
my $inputBinaryROMFile               = ""; # For just signing the boot sector of a prepared ROM image
my $inputFromBinaryROM               = 0;
my $flashBlockMapFile                = undef;

# For flexible parts of flash layout
my $mainICDoffset                    = undef;

# Will build up a list of all reserve section info in ROM image in here
my @reserveSecs                      = ();
my $cryptocoreSigning                = 0;  # Are we Cryptocore signing?
my $masterCPUBootSlot;                     # Will be set to the number of the slot containing
                                           # the boot image for the master CPU (CPU 0)
my @bootSlots                        = (); # List of bootable slots
my @slots                            = (); # Slot to CPU mapping array
my @cpusWithApps                     = (); # CPUs we have app images for

# Used to keep a list of the ranges that have been used in our representation
# of FLASH
my @usedRanges                       = ();

# 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_rom_image>\n",
        "                    -v <boot_vector_image/elf_file>[:cpu][%default_sec_type]\n",
        "                    -s <bootstrap_image/elf_file>[:cpu][%default_sec_type]\n",
        "                    -i <application_image/elf_file>[\@slot][:cpu][%default_sec_type]\n",
        "                    -fs <application_image/elf_file>[%default_sec_type]\n",
        "                    -a <alignment>\n",
        "                    -b <slot>\n",
        "                    -flashbase <flash_base_address>\n",
        "                    -flashmap <flash_block_map_file>\n",
        "                    -t <chip_type>\n",
        "                    -V[n]\n",
        " (the following are only useful on Cryptocore parts)\n",
        "                    -d <binary_sigdma_file> <sigdma_info_file>\n",
        "                    -d <sigdma_info_file>\n",
        "                    -k <signing_key_file>\n",
        "                    -f <firmware_key_file>\n",
        "                    -setbssize <boot_sec_size>\n",
        "                    -signbinary <input_binary_rom_image>\n",
        "                    -sksig <signing_key_signature_file>\n",
        "                    -stc <addr> <value>\n",
        "                    -vcc <addr> <value>\n\n",
        " where:\n",
        "  -o    specifies an output ROM image file\n",
        "  -v    specifies a boot vector image/ELF file.  If ELF, is for cpu (default 0) \n",
        "        with sections of default_sec_type (default is pic, other option is inplace)\n",
        "  -s    specifies a bootstrap image/ELF file.  If ELF, is for cpu (default 0) \n",
        "        with sections of default_sec_type (default is pic, other option is inplace)\n",
        "  -i    specifies an application image/ELF file (may be a relocatable library) and\n",
        "        optional slot number, cpu (default 0) and default_sec_type (default is copy,\n",
        "        other options are deflate, pic or inplace)\n",
        "  -fs   specifies a fail-safe application image/ELF file and optional default_sec_type (default\n",
        "        is copy, other options are deflate or inplace).  The fail-safe application\n",
        "        always runs after the bootstrap on the master CPU.  It is supposed to do any\n",
        "        checks and actions needed (e.g. repair FLASH after update failure), then load\n",
        "        the boot application for the master CPU\n",
        "  -a    specifies the minimum section alignment for sections placed by this\n",
        "        script (default 64)\n",
        "  -b    specifies the slot number which contains the boot application\n",
        "  -flashbase    overrides the default flash base address (0) for boards with\n",
        "                flash at a different address\n",
        "  -flashmap     when a fail-safe application is provided along with a flash block map\n",
        "                file, $THIS_SCRIPT will separate fixed and updatable areas in FLASH into\n",
        "                separate FLASH blocks so the bottom blocks can be locked\n",
        "  -t    specifies a chip type (used to switch to STi5528 layout, set minimum section\n",
        "        alignments for some chips, or for retrieving Cryptocore information)\n",
        "  -V[n] specifies verbose mode (verbosity level n)\n",
        " (the following are only useful on Cryptocore parts)\n",
        "  -d    specifies SigDMA file(s), which can be a SigDMA info file (containing\n",
        "        the SigDMA data and info), or a binary file for the data and a\n",
        "        SigDMA info file\n",
        "        Note: Multiple SigDMAs can be placed within one image to save space in\n",
        "        the image directory if mkimage.pl is used to prepare them\n",
        "  -k    specifies a signing key file to sign with\n",
        "  -f    specifies firmware key file to sign signing key with (Cryptocore 2)\n",
        "  -setbssize    specifies the Cryptocore boot sector size to be used, overriding\n",
        "                calculated or existing values (in bytes)\n",
        "  -signbinary   specifies an input binary ROM image to Cryptocore sign the boot sector of\n",
        "                (use -setbssize too if boot sector size field is not already in place)\n",
        "  -sksig        specifies a file containing a pre-signed version of the signing key\n",
        "                signature so that a firmware key is not needed (Cryptocore 2)\n",
        "  -stc  specifies a Sales Type Check address and value for the boot sector (Cryptocore 2)\n",
        "  -vcc  specifies a Version Control Check address and value for the boot sector (Cryptocore 2)\n");
  exit(1);
}

#
# Sub to convert an ELF file to an image file by calling mkimage.pl
# 1st arg is type of ELF file: "bootvec", "bootstrap" or "app"
# 2nd arg is a filename
# Returns filname as is on failure, or new filename on success
#
sub convertIfElf($$)
{
  my $elfType = shift(@_);
  my $filename = shift(@_);

  my ($elfFilename, $baseName);
  # Set defaults for the cpu and default section type
  my $cpu = 0;
  my $defSecType = ($elfType eq "app" ? "copy" : "pic");
  my $elfArg = "-e";

  # We'll need to extract the filename from $filename (it may have '@', ':', or
  # '%' options following)
  if ($filename =~ /^((?:[a-zA-Z]\:\\)?[^\@\:\%]+)/)
  {
    $elfFilename = $1;
    ($baseName, $null, $null) = fileparse($elfFilename, "\\..*");

    unless(-f $elfFilename)
    {
      die("$elfFilename does not exist, stopped");
    }

    # Lets check it's an ELF file
    # First check the magic number at the start of the file - only try readelf
    # if this is okay (the magic number COULD be there by chance...)
    open(IN_HANDLE, "<$elfFilename") || die("could not open $elfFilename for reading ($!), stopped");
    binmode(IN_HANDLE);
    my $binStr;
    sysread(IN_HANDLE, $binStr, 4) || die("unable to read from '$elfFilename' ($!), stopped");
    close(IN_HANDLE);
    my $err = 1; # Start off assuming not an ELF file (0 later implies it is)
    if (unpack("N", $binStr) == $ELF_MAGIC_NUMBER)
    {
      # Correct magic number - use readelf
      my $cmd = getReadelf() . " -h $elfFilename";
      print("Running command: $cmd\n") if ($verboseOutput > 1);
      open(OLDERR, ">&STDERR");
      close(STDERR);
      # We need STDERR to exist and be redirected or it may get printed to the
      # console anyway
      my $tmpFile = createtmpname();
      open(STDERR, ">$tmpFile");
      if ($elfType eq "app")
      {
        # Check whether this is a standalone app, or a relocatable library by
        # checking the Type line in the header (if it is DYN it is an RL)
        my @output = `$cmd`;
        unless (scalar(@output) > 0)
        {
          # We need to put stderr back before die can print a message
          close(STDERR);
          open(STDERR, ">&OLDERR");
          close(OLDERR);
          die("unable to run " . getReadelf() . ", stopped");
        }
        for my $line (@output)
        {
          if ($line =~ /\s*Type:\s+DYN\s+/)
          {
            $elfType = "reloc";
            $elfArg = "-r";
            $err = 0;
            last;
          }
          elsif ($line =~ /\s*Type:\s+EXEC\s+/)
          {
            $err = 0;
          }
        }
      }
      else
      {
        open(OLDOUT, ">&STDOUT");
        close(STDOUT);
        $err = system($cmd);
        open(STDOUT, ">&OLDOUT");
        close(OLDOUT);
      }
      close(STDERR);
      open(STDERR, ">&OLDERR");
      close(OLDERR);
    }

    if ($err)
    {
      print("$elfFilename is not a 'DYN' or 'EXEC' ELF file - assuming it is an image\n") if ($verboseOutput);
      return $filename;
    }
    else
    {
      print("$elfFilename is an '$elfType' ELF file - converting to an image...\n") if ($verboseOutput);
    }
  }

  # Extract a cpu if specified
  if ($filename =~ /^(?:[a-zA-Z]\:\\)?[^\:]+\:([0-9]+)/)
  {
    $cpu = $1;
  }
  elsif ($filename =~ /^(?:[a-zA-Z]\:\\)?[^\:]+\:([^\@\%]+)/)
  {
    usage("invalid CPU number '$1' in '$filename'\n");
  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -