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

📄 mkbinrom.pl

📁 采用ST20 CPU的机顶盒的烧写程序
💻 PL
📖 第 1 页 / 共 5 页
字号:
  {
    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 + -