wrapflash.pl 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  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 = 0xe201e7eb;
  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($zlen,$dlen,$dcrc,$address) = @_;
  18. my $hdr = pack("V*", $SPIFLASH_MAGIC, $zlen, $dlen, $dcrc, $address,
  19. 0, 0);
  20. $hdr .= pack("V", Digest::CRC::crc32($hdr));
  21. return $hdr;
  22. }
  23. my $outfile = shift @ARGV;
  24. if (!defined($outfile)) {
  25. die "Usage: $0 outfile [infile addr]...\n";
  26. }
  27. open(my $out, '>', $outfile)
  28. or die "$0: $outfile: $!\n";
  29. binmode($outfile);
  30. my $err;
  31. while (1) {
  32. my $infile = shift @ARGV;
  33. my $inaddr = getint(shift @ARGV);
  34. last if (!defined($infile));
  35. my $in;
  36. if (!open($in, '<', $infile)) {
  37. $err = "$infile: $!";
  38. last;
  39. }
  40. binmode($in);
  41. my $data;
  42. my $zlen = read($in, $data, $MAX_DATA_LEN);
  43. close($in);
  44. my $dlen = $zlen;
  45. if (substr($in, 0, 3) == "\37\213\10") {
  46. # gzip file
  47. $dlen = unpack("V", substr($data, -4));
  48. }
  49. my $dcrc = Digest::CRC::crc32($data);
  50. print $out makeheader($zlen, $dlen, $dcrc, $inaddr);
  51. print $out $data;
  52. if ($zlen & 3) {
  53. # pad to dword boundary
  54. print $out "\0" x ((4-$zlen) & 3);
  55. }
  56. }
  57. if (defined($err)) {
  58. close($out);
  59. unlink($outfile);
  60. die "$0: $err\n";
  61. }
  62. print $out makeheader(0, 0, Digest::CRC::crc32(''), 0);
  63. close($out);