You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

disrom.pl 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #!/usr/bin/perl -w
  2. #
  3. # Program to display key information about a boot ROM
  4. # including PCI and PnP structures
  5. #
  6. # GPL, Ken Yap 2001
  7. #
  8. use bytes;
  9. sub getid ($)
  10. {
  11. my ($offset) = @_;
  12. return '' if ($offset == 0 or $offset > $len);
  13. my ($string) = unpack('Z32', substr($data, $offset, 32));
  14. return ($string);
  15. }
  16. sub dispci
  17. {
  18. my ($pcidata) = substr($data, $pci, 0x18);
  19. my ($dummy, $vendorid, $deviceid, $vpd, $pcilen, $pcirev,
  20. $class1, $class2, $class3, $imglen, $coderev, $codetype,
  21. $indicator) = unpack('a4v4C4v2C2', $pcidata);
  22. $imglen *= 512;
  23. my $vendorstr = sprintf('%#04x', $vendorid);
  24. my $devicestr = sprintf('%#04x', $deviceid);
  25. my $coderevstr = sprintf('%#04x', $coderev);
  26. print <<EOF;
  27. PCI structure:
  28. Vital product data: $vpd
  29. Vendor ID: $vendorstr
  30. Device ID: $devicestr
  31. Device base type: $class1
  32. Device sub type: $class2
  33. Device interface type: $class3
  34. Image length: $imglen
  35. Code revision: $coderevstr
  36. Code type: $codetype
  37. Indicator: $indicator
  38. EOF
  39. }
  40. sub dispnp
  41. {
  42. my ($pnpdata) = substr($data, $pnp, 0x20);
  43. my ($dummy1, $pnprev, $pnplen, $nextpnp, $dummy2,
  44. $pnpcsum, $deviceid, $mfrid, $productid,
  45. $class1, $class2, $class3, $indicator,
  46. $bcv, $dv, $bev, $dummy, $sri) = unpack('a4C2vC2a4v2C4v5', $pnpdata);
  47. print <<EOF;
  48. PnP structure:
  49. EOF
  50. print 'Vendor: ', &getid($mfrid), "\n";
  51. print 'Device: ', &getid($productid), "\n";
  52. my $indicatorstr = sprintf('%#02x', $indicator);
  53. my $bcvstr = sprintf('%#04x', $bcv);
  54. my $dvstr = sprintf('%#04x', $dv);
  55. my $bevstr = sprintf('%#04x', $bev);
  56. my $sristr = sprintf('%#04x', $sri);
  57. my $checksum = unpack('%8C*', $pnpdata);
  58. print <<EOF;
  59. Device base type: $class1
  60. Device sub type: $class2
  61. Device interface type: $class3
  62. Device indicator: $indicatorstr
  63. Boot connection vector: $bcvstr
  64. Disconnect vector: $dvstr
  65. Bootstrap entry vector: $bevstr
  66. Static resource information vector: $sristr
  67. Checksum: $checksum
  68. EOF
  69. }
  70. sub pcipnp
  71. {
  72. ($pci, $pnp) = unpack('v2', substr($data, 0x18, 4));
  73. if ($pci >= $len or $pnp >= $len) {
  74. print "$file: Not a PCI PnP ROM image\n";
  75. return;
  76. }
  77. if (substr($data, $pci, 4) ne 'PCIR' or substr($data, $pnp, 4) ne '$PnP') {
  78. print "$file: No PCI and PNP structures, not a PCI PNP ROM image\n";
  79. return;
  80. }
  81. &dispci();
  82. &dispnp();
  83. }
  84. $file = $#ARGV >= 0 ? $ARGV[0] : '-';
  85. open(F, "$file") or die "$file: $!\n";
  86. binmode(F);
  87. # Handle up to 64kB ROM images
  88. $len = read(F, $data, 64*1024);
  89. close(F);
  90. defined($len) or die "$file: $!\n";
  91. substr($data, 0, 2) eq "\x55\xAA" or die "$file: Not a boot ROM image\n";
  92. my ($codelen) = unpack('C', substr($data, 2, 1));
  93. $codelen *= 512;
  94. if ($codelen < $len) {
  95. my $pad = $len - $codelen;
  96. print "Image is $codelen bytes and has $pad bytes of padding following\n";
  97. $data = substr($data, 0, $codelen);
  98. } elsif ($codelen > $len) {
  99. print "Image should be $codelen bytes but is truncated to $len bytes\n";}
  100. &pcipnp();
  101. ($csum) = unpack('%8C*', $data);
  102. print "ROM checksum: $csum \n";
  103. exit(0);