Hi everybody,
Yesterday, I sent out a request for the format of loadable Qlogic ISP
firmware as used by DU driver for Qlogic 1020/1040 cards. I got a single
reply from Johan Danielsson (joda_at_pdc.kth.se), which was right on the
money. Using information kindly provided by Johan, I wrote a Q&D perl
script (attached at the end of this message) which extracts Qlogic firmware
from x86 boot PROM and converts it to the format understood by DU driver.
The boot PROM itself is available from the Qlogic's web site at
http://www.qlc.com. It can also be extracted from the card itself if
you care to put the card into a PC.
Our ISP1040 (which cost us less than a half of the Digital's price for
the equivalent KZPBA adapter) now works fine. Once again, many thanks
to Johan Danielsson.
Regards,
/Serge.P
----- Ain't Perl great?
#!/freeware/bin/perl5 -w
#
# Builds /dev/qlogic/isp_fw.mod from x86 boot PROM of the Qlogic 1040
# adapter.
#
# Extract firmware from the x86 ROM image
$file = `cat $ARGV[0]` ;
die "$ARGV[0] is not a ROM image" unless( length($file) == 0x10000 ) ;
$begin = unpack('v',substr($file,0x11,2)) ;
printf "Firmware begins at %x\n", $begin ;
die "Firmware offset is not in ROM image"
unless( $begin > 0x11 && $begin < length($file) ) ;
$length = unpack('v',substr($file,$begin+6,2)) * 2 ;
printf "Firmware image length is %x bytes\n", $length ;
die "Firmware end is past the ROM image"
unless( $length > 0 && $begin+$length <= length($file) ) ;
$firmware = substr($file,$begin,$length) ;
$swapware = pack('s*',unpack('n*',$firmware)) ;
substr($swapware,10) =~ /([^\0]*)\0([^\0]*)\0/ ;
die "ID message is missing in firmware" unless( $1 ne "" && $2 ne "" ) ;
($id1,$id2) = ($1,$2) ;
print "Firmware image identification strings are:\n$id1\n$id2\n" ;
$id2 =~ /Version ([0-9]{2})\.([0-9]{2}) / ;
die "Can't extract firmware version from the second ID string" unless( $1 ne "" && $2 ne "" ) ;
$riskMajor = $1 ;
$riskMinor = $2 ;
print "Firmware version is $riskMajor.$riskMinor\n" ;
# Convert firmware to compilable C code
_at_riscCode = unpack('S*',$firmware) ;
foreach (_at_riscCode){ $_ = sprintf "0x%04x", $_ ; }
$riscString = join(', ',_at_riscCode) ;
$riscLength = $#riscCode + 1 ;
$riscVersion = $riskMajor*1024 + $riskMinor ;
open(FRM,"> isp_fw.c") || die "Can't create isp_fw.c" ;
write FRM ;
close(FRM) || die "Can't close isp_fw.c" ;
print "Created C source for the firmware image, compiling ...\n" ;
$rc = system("cc -c -non_shared -o isp_fw.mod isp_fw.c") ;
die "Can't run C compiler, rc = $rc" unless( $rc == 0 ) ;
print "Firmware image stored in isp_fw.mod\n" ;
format FRM =
unsigned short risc_code_version = _at_<<<<<<<<< ;
$riscVersion
unsigned short risc_code_addr01 = 0x1000 ;
unsigned short risc_code01[] = {
^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~~
$riscString
} ;
unsigned short risc_code_length01 = _at_<<<<<<<<< ;
$riscLength
.
---- end of the script
Received on Mon Aug 31 1998 - 17:18:57 NZST