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

📄 mkcommon.pm

📁 采用ST20 CPU的机顶盒的烧写程序
💻 PM
📖 第 1 页 / 共 3 页
字号:
      {
        if ($line =~ /^([0-9a-f]{8})\s+g\s+\*ABS\*\s+[0-9a-f]{8}\s+$symbol/)
        {
          $addr{$symbol} = hex($1);
          if (scalar(values(%addr)) == scalar(@interestingSyms))
          {
            last READ;
          }
        }
      }
    }
    close(SYMINFO);
    # If we didn't see all the interesting symbols, we can only assume this app
    # will be running in 29-bit mode and fall-through to using the usual P0
    # masking.
    if (scalar(keys(%addr)) == scalar(@interestingSyms))
    {
      if ($addr{".physrambase"} != ($addr{"___rambase"} &&
          $addr{".physrambase"} != ($addr{"___rambase"} & 0x1FFFFFFF)))
      {
        # The physical RAM base is not an identity mapping or a P0 version of
        # ___rambase (the usable RAM base), so we must be talking virtual memory
        # and will probably have to calculate the physical address of $inAddr...
        
        # If $inAddr is not in the range of RAM, we'll have to assume it is
        # a physical address already as we can't know the physical <-> virtual
        # mapping.
        if (overlaps($inAddr, $inAddr + 1, $addr{"___rambase"},
                     $addr{"___rambase"} + $addr{"___ramsize"}))
        {
          $physAddr = ($inAddr - $addr{"___rambase"}) + $addr{".physrambase"};
        }
      }
    }
  }
  
  if (!defined($physAddr))
  {
    $physAddr = $inAddr & 0x1FFFFFFF;
  }
  return $physAddr;
}

#
# Sub to read chip specific info like the boot sector gap low and high
# addresses, the Cryptocore version, and how many of the config_table entry
# fields are being signed with signed blocks from a chip info file (1st arg)
# These are returned in an array
sub getChipInfo($$;$)
{
  my $chipInfoFile = shift(@_);
  my $chip = shift(@_);
  my $flashStart = undef;
  if (@_ > 0)
  {
    $flashStart = shift(@_);
  }
  
  if (!(-f $chipInfoFile))
  {
    # When there is no chipinfo file present, don't complain, but return an
    # empty list.  If the values are needed we will complain later.
    return ();
  }

  # Store values to be returned
  my $host_boot_gap_low_ind   = 0;
  my $host_boot_gap_high_ind  = 1;
  my $cryptocore_version_ind  = 2;
  my $cte_signing_level_ind   = 3;
  my @retArray = ();
  
  open(IN_FILE, $chipInfoFile) || die("could not open $chipInfoFile for " .
                                      "reading ($!), stopped");
  
  # Read to the correct chip
  my $line;
  my $atChip = 0;
  while (!$atChip && ($line = <IN_FILE>))
  {
    if ($line =~ /^\[$chip\]/i)
    {
      $atChip = 1;
    }
  }
  
  if ($atChip)
  {
    # Read host_boot_gap_low and high
    while ($atChip && ($line = <IN_FILE>))
    {
      if ($line =~ /^\s*host_boot_gap_low\s+(0[Xx][0-9A-Fa-f]+)(\s+relative)?/)
      {
        $retArray[$host_boot_gap_low_ind] = hex($1);
        if (defined($2) && defined ($flashStart) && $2 =~ /relative/)
        {
          # Gap address is relative to given $flashStart (boot gap above boot
          # vector assumed).
          $retArray[$host_boot_gap_low_ind] += $flashStart
        }
        # Must be 32 byte aligned
        if ($retArray[$host_boot_gap_low_ind] % 32)
        {
          die("host_boot_gap_low for $chip in $chipInfoFile must be 32 byte aligned, stopped");
        }
      }
      elsif ($line =~ /^\s*host_boot_gap_high\s+(0[Xx][0-9A-Fa-f]+)(\s+relative)?/)
      {
        $retArray[$host_boot_gap_high_ind] = hex($1);
        if (defined($2) && defined ($flashStart) && $2 =~ /relative/)
        {
          # Gap address is relative to given $flashStart (boot gap above boot
          # vector assumed).
          $retArray[$host_boot_gap_high_ind] += $flashStart;
        }
        # Must be 32 byte aligned
        if ($retArray[$host_boot_gap_high_ind] % 32)
        {
          die("host_boot_gap_high for $chip in $chipInfoFile must be 32 byte aligned, stopped");
        }
      }
      elsif ($line =~ /^cryptocore_version\s+(\S+)/)
      {
        $retArray[$cryptocore_version_ind] = $1;
        # Supported Cryptocore version check
        if ($retArray[$cryptocore_version_ind] < 1.0 ||
            $retArray[$cryptocore_version_ind] > 2.0)
        {
          die("cryptocore_version for $chip in $chipInfoFile is " .
              "$retArray[$cryptocore_version_ind], but only Cryptocore " .
              "versions 1.0 to 2.0 are supported, stopped");
        }
      }
      elsif($line =~ /^public_exponent\s+(-?[0-9]+)/)
      {
        # Use global as all signing done in this module
        $publicExponent = $1;
      }
      elsif($line =~ /^cte_signing_level\s+([0-9]+)/)
      {
        $retArray[$cte_signing_level_ind] = $1;
        if ($retArray[$cte_signing_level_ind] < 1 ||
            $retArray[$cte_signing_level_ind] > 4)
        {
          die("cte_signing_level for $chip in $chipInfoFile must between 1 " .
              "and 4 - see comments in the file for more information, stopped");
        }
      }
      elsif($line =~ /^stc_addr\s+(0[Xx][0-9A-Fa-f]+)/)
      {
        die("Sales Type Check address in $chipInfoFile is no longer supported - use command line options, stopped");
      }
      elsif($line =~ /^vcc_addr\s+(0[Xx][0-9A-Fa-f]+)/)
      {
        die("Version Control Check address in $chipInfoFile is no longer supported - use command line options, stopped");
      }
      elsif ($line =~ /^\[[^]]+\]/)
      {
        $atChip = 0;
      }
    }
  }
  else
  {
    close(IN_FILE);
    listChips($chipInfoFile);
    die("chip information for chip $chip not found, stopped");
  }
  close(IN_FILE);
  
  if (!defined($retArray[$host_boot_gap_low_ind]) ||
      !defined($retArray[$host_boot_gap_high_ind]))
  {
    die("chip information for chip $chip incomplete - ensure " .
        "host_boot_gap_low and host_boot_gap_high are specified in " .
        "$chipInfoFile, stopped");
  }
  # Set defaults if not specified in file
  if (!defined($retArray[$cryptocore_version_ind]))
  {
    $retArray[$cryptocore_version_ind] = 1.5;
  }
  if (!defined($retArray[$cte_signing_level_ind]))
  {
    $retArray[$cte_signing_level_ind] = 4;
  }
  return @retArray;
}

#
# List chip types from given chip info file
#
sub listChips($)
{
  my $chipInfoFile = shift(@_);
  open(IN_FILE, $chipInfoFile) || die("could not open $chipInfoFile for reading ($!), stopped");
  print("Defined chips in $chipInfoFile are:\n");
  my $line;
  while ($line = <IN_FILE>)
  {
    if ($line =~ /^\[([^\]]+)\]/)
    {
      print("  $1\n");
    }
  }
  close(IN_FILE);
}

#
# Sub to run the signing tool given the key filename, the name of the file
# containing the block to sign and the filename to put the signature in
#
# We use siggen in binary mode (faster, smaller files, and we're already in the
# write format compared to using big endian ASCII word lists - the other input
# type accepted)
#
# We also allow the key generation command line, but -genkey would be in
# $blockToSignFilename and the number of bits in $sigFilename).
#
sub runSigningTool($$$$$$$)
{
  my $keyFile = shift(@_);
  my $blockToSignFilename = shift(@_);
  my $sigFilename = shift(@_);
  my $sigVCCAddr = shift(@_);
  my $sigVCCValue = shift(@_);
  my $sigSTCAddr = shift(@_);
  my $sigSTCValue = shift(@_);
  my @cmdLine;
  # Run siggen, passing the name of the temporary file containing the block to 
  # be signed, the name of the key file and the name of the signature file to
  # generate
  my $err = 0;

  @cmdLine = ($::SIGGEN_TOOL, $blockToSignFilename, $keyFile, $sigFilename);
  if ($keyFile ne "-genkey")
  {
    push(@cmdLine, "-b");
  }
  if (defined($sigSTCValue) && defined($sigSTCAddr) && $sigSTCAddr != 0)
  {
    push(@cmdLine, "-stc", $sigSTCAddr, $sigSTCValue);
  }
  if (defined($sigVCCValue) && defined($sigVCCAddr) && $sigVCCAddr != 0)
  {
    push(@cmdLine, "-vcc", $sigVCCAddr, $sigVCCValue);
  }
  if (defined($publicExponent) && $publicExponent != $DEFAULT_PUBLIC_EXPONENT)
  {
    push(@cmdLine, "-e", $publicExponent);
  }
 
  push(@cmdLine, "-z$verboseOutput") if ($verboseOutput);
  
  if ($siggen_on_path)
  {
    open(OLDERR, ">&STDERR");
    close(STDERR);
    
    print("Running command: " . join(" ", @cmdLine) . "\n") if ($verboseOutput > 1);
    $err = system(@cmdLine);
    
    open(STDERR, ">&OLDERR");
    close(OLDERR);
    if ($err)
    {
      warn("Warning: $::SIGGEN_TOOL execution failed (may not be on path).  " .
           "Trying location of $::THIS_SCRIPT...\n");
      $siggen_on_path = 0;
    }
  }
  if ($err || !$siggen_on_path)
  {
    my $oldErr = $err;
    my $siggenFullPath = $::PATH_TO_THIS_SCRIPT;
    $siggenFullPath = "./" if ($siggenFullPath eq "");
    if (-e $siggenFullPath . "$::SIGGEN_TOOL")## && -x $siggenFullPath . "$SIGGEN_TOOL")
    {
      $cmdLine[0] = $siggenFullPath . "$::SIGGEN_TOOL";
      print("Running command: " . join(" ", @cmdLine) . "\n") if ($verboseOutput > 1);
      $err = system(@cmdLine);
    }
    if ($err)
    {
      print("\n");
      die("error attempting to run signing tool: " . $! . "\nstopped");
    }
    elsif ($oldErr)
    {
      print("Signature generation succeeded!\n");
    }
  }
}

#
# Sub which fills undefined values with 0 in a given list (returning a new list
# if 1st argument is non-zero)
# Prevents use of undefined value errors when script is launched with the -w
# switch (but does increase memory usage for a sparce array)
# A 3rd argument may optionally be specified to specify a value to insert in
# undefined entries other than 0
sub noUndef($$;$)
{
  my $noModsToInputList = shift(@_);
  my $inListRef = shift(@_);
  my $fillValue = 0;
  $fillValue = shift(@_) if (scalar(@_) > 0);
  

  my $outListRef;
  my @newList = ();
  if ($noModsToInputList)
  {
    $outListRef = \@newList;
  }
  else
  {
    $outListRef = $inListRef;
  }
  
  for (my $count = 0; $count < scalar(@$inListRef); $count++)
  {
    if (!defined($inListRef->[$count]))
    {
      $outListRef->[$count] = $fillValue;
    }
    elsif ($noModsToInputList)
    {
      $outListRef->[$count] = $inListRef->[$count];
    }
  }
  return $outListRef;
}

#
# Sub to convert an int to little endian bytes
#
sub intToLittleEndBytes($)
{
  my @bytes = unpack("C4", pack("V", shift(@_)));
  
  return @bytes;
}

#
# Sub to convert a hex string to a byte array
# Returns a reference to the array
sub hexStrToByteArray($)
{
  my $str = shift(@_);
  my @byteArray = map(hex, unpack("A2" x (length($str) / 2), $str));
  return \@byteArray;
}

#
# Sub to pad a list up to the given number of entries (with 0 entries)
# Returns a new list
sub padList($$)
{
  my $num = shift(@_);
  my $arrayRef = shift(@_);
  my @list = @$arrayRef;
  my $pad = $num - scalar(@list);
  if ($pad > 0)
  {
    push(@list, (0) x $pad);
  }
  return \@list;
}

⌨️ 快捷键说明

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