#!/usr/bin/perl -w # Extract Symbol firmware and convert is to a header file and two binary # files. # Copyright (C) 2004 Pavel Roskin # This script is Free Software, and it can be copied, distributed and # modified as defined in the GNU General Public License. A copy of # its license can be downloaded from http://www.gnu.org/copyleft/gpl.html # Usage: # parse_symbol_fw infile header binfile1 binfile2 use strict; use open IN => ":raw", OUT => ":raw"; # Print message and exit (like "die", but without raising an exception). # Newline is added at the end. sub error { printf STDERR "ERROR: "; printf STDERR @_; printf STDERR "\n"; exit 1; } sub readnum_ba () { my $byte_a; read INFILE,$byte_a,1; my $byte_b; read INFILE,$byte_b,1; return (ord($byte_b) << 8) + ord($byte_a); } if ($#ARGV != 3) { error ("Usage: parse_symbol_fw infile header binfile1 binfile2"); } unless (open (INFILE, "< $ARGV[0]")) { error ("couldn't open $ARGV[0] for reading: $!"); } unless (open (OUTFILE, "> $ARGV[1]")) { error ("couldn't open $ARGV[1] for writing: $!"); } # Process one array, either for primary or for secondary firmware sub process_one_array($$) { my $arrname = shift(@_); my $binfile = shift(@_); my $offset = -1; my $str_offset = 0; # Skip to the beginning of firmware $/ = "\x00"; while () { if (m{FILE: }g) { $offset = $str_offset + pos() - 6; last; } $str_offset = tell(INFILE); } if ($offset == -1) { error("Cannot find FILE: marker"); } my @fwdata = split; print $fwdata[1] . "\n"; seek(INFILE, $offset, 0); my $blknum = $fwdata[3]; my $pdrlen = $fwdata[4]; my $crclen = $fwdata[5]; my $compatlen = $fwdata[6]; while (!eof(INFILE)) { my $byte; read INFILE, $byte, 1; last if (ord($byte) == 0x1a); } # Walk all blocks my $block = $blknum; while ($block-- > 0) { seek(INFILE, 4, 1); my $len = readnum_ba(); seek(INFILE, $len, 1); } my $img_len = tell(INFILE) - $offset + $pdrlen + $crclen + $compatlen + 2; seek(INFILE, $offset, 0); # Write binary file for the section unless (open (BINFILE, "> $binfile")) { error ("couldn't open $binfile for writing: $!"); } # Output the array printf OUTFILE "/* %s %s */\n", $fwdata[1], $fwdata[2]; printf OUTFILE "static u8 %s[] = {\n", $arrname; my $count = 0; while ($count++ < $img_len) { my $byte; read INFILE, $byte, 1; $byte = ord($byte); printf OUTFILE "0x%02x,", $byte; printf BINFILE "%c", $byte; if ($count % 16 == 0) { printf OUTFILE "\n"; } } if ($img_len % 16) { printf OUTFILE "\n"; } print OUTFILE "};\n"; close(BINFILE); } process_one_array("primsym", $ARGV[2]); process_one_array("secsym", $ARGV[3]); close(INFILE); close(OUTFILE);