#!/usr/bin/perl use strict; use integer; use Digest::CRC; my $MAX_DATA_LEN = 16 << 20; my $SPIFLASH_MAGIC = 0xe301e7eb; sub getint($) { my($s) = @_; return ($s =~ /^0/) ? oct $s : $s+0; } sub filelen($) { my($f) = @_; my @s = stat($f); return $s[7]; } sub makeheader($$$$$) { my($target,$zlen,$dlen,$dcrc,$address) = @_; my $hdr = pack("V*", $SPIFLASH_MAGIC, $zlen, $dlen, $dcrc, $address); $hdr .= substr($target.("\0" x 8), 0, 8); $hdr .= pack("V", Digest::CRC::crc32($hdr)); return $hdr; } my $target = shift @ARGV; my $outfile = shift @ARGV; if (!defined($outfile)) { die "Usage: $0 target_name outfile [infile addr]...\n"; } open(my $out, '>', $outfile) or die "$0: $outfile: $!\n"; binmode($outfile); my $err; while (1) { my $infile = shift @ARGV; my $inaddr = getint(shift @ARGV); last if (!defined($infile)); my $in; if (!open($in, '<', $infile)) { $err = "$infile: $!"; last; } binmode($in); my $data; my $zlen = read($in, $data, $MAX_DATA_LEN); close($in); my $dlen = $zlen; if (substr($in, 0, 3) == "\37\213\10") { # gzip file $dlen = unpack("V", substr($data, -4)); } my $dcrc = Digest::CRC::crc32($data); print $out makeheader($target, $zlen, $dlen, $dcrc, $inaddr); print $out $data; if ($zlen & 3) { # pad to dword boundary print $out "\0" x ((4-$zlen) & 3); } } if (defined($err)) { close($out); unlink($outfile); die "$0: $err\n"; } print $out makeheader($target, 0, 0, Digest::CRC::crc32(''), 0); close($out);