130 lines
2.6 KiB
Plaintext
130 lines
2.6 KiB
Plaintext
|
#!/usr/bin/perl -w
|
||
|
|
||
|
# Extract Symbol firmware and convert is to a header file and two binary
|
||
|
# files.
|
||
|
|
||
|
# Copyright (C) 2004 Pavel Roskin <proski@gnu.org>
|
||
|
|
||
|
# 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;
|
||
|
|
||
|
# 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 (<INFILE>) {
|
||
|
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);
|