wrapflash.pl 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #!/usr/bin/perl
  2. use strict;
  3. use integer;
  4. use Digest::CRC;
  5. my $MAX_DATA_LEN = 16 << 20;
  6. my $SPIFLASH_MAGIC = 0xe301e7eb;
  7. sub getint($) {
  8. my($s) = @_;
  9. return ($s =~ /^0/) ? oct $s : $s+0;
  10. }
  11. sub filelen($) {
  12. my($f) = @_;
  13. my @s = stat($f);
  14. return $s[7];
  15. }
  16. sub makeheader($$$$$) {
  17. my($target,$zlen,$dlen,$dcrc,$address) = @_;
  18. my $hdr = pack("V*", $SPIFLASH_MAGIC, $zlen, $dlen, $dcrc, $address);
  19. $hdr .= substr($target.("\0" x 8), 0, 8);
  20. $hdr .= pack("V", Digest::CRC::crc32($hdr));
  21. return $hdr;
  22. }
  23. my $target = shift @ARGV;
  24. my $outfile = shift @ARGV;
  25. if (!defined($outfile)) {
  26. die "Usage: $0 target_name outfile [infile addr]...\n";
  27. }
  28. open(my $out, '>', $outfile)
  29. or die "$0: $outfile: $!\n";
  30. binmode($outfile);
  31. my $err;
  32. while (1) {
  33. my $infile = shift @ARGV;
  34. my $inaddr = getint(shift @ARGV);
  35. last if (!defined($infile));
  36. my $in;
  37. if (!open($in, '<', $infile)) {
  38. $err = "$infile: $!";
  39. last;
  40. }
  41. binmode($in);
  42. my $data;
  43. my $zlen = read($in, $data, $MAX_DATA_LEN);
  44. close($in);
  45. my $dlen = $zlen;
  46. if (substr($in, 0, 3) == "\37\213\10") {
  47. # gzip file
  48. $dlen = unpack("V", substr($data, -4));
  49. }
  50. my $dcrc = Digest::CRC::crc32($data);
  51. print $out makeheader($target, $zlen, $dlen, $dcrc, $inaddr);
  52. print $out $data;
  53. if ($zlen & 3) {
  54. # pad to dword boundary
  55. print $out "\0" x ((4-$zlen) & 3);
  56. }
  57. }
  58. if (defined($err)) {
  59. close($out);
  60. unlink($outfile);
  61. die "$0: $err\n";
  62. }
  63. print $out makeheader($target, 0, 0, Digest::CRC::crc32(''), 0);
  64. close($out);