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.

mntnbi.pl 2.7KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #!/usr/bin/perl -w
  2. #
  3. # Quick Perl program to decode and display details about
  4. # tagged images created by mknbi, and then mount the contained
  5. # DOS filesystem using a loop-back mount
  6. #
  7. # Martin Atkins, November 1998
  8. # by hacking disnbi by
  9. # Ken Yap, September 1998
  10. #
  11. #
  12. sub getvendordata {
  13. my ($flags) = @_;
  14. my $vendordata = '';
  15. my $vendorlen = ($flags & 0xff) >> 4;
  16. if ($vendorlen > 0) {
  17. $vendorlen *= 4;
  18. $vendordata = unpack("A$vendorlen", substr($imageheader, $curoffset));
  19. $curoffset += $vendorlen;
  20. }
  21. return ($vendordata);
  22. }
  23. sub decodesegmentflags {
  24. my ($flags) = @_;
  25. $flags >>= 24;
  26. $flags &= 0x3;
  27. ($flags == 0) and $type = "Absolute";
  28. ($flags == 1) and $type = "Follows last segment";
  29. ($flags == 2) and $type = "Below end of memory";
  30. ($flags == 3) and $type = "Below last segment loaded";
  31. return ($type);
  32. }
  33. sub onesegment
  34. {
  35. my ($segnum) = @_;
  36. my ($type, $vendordata);
  37. my ($flags, $loadaddr, $imagelen, $memlength) = unpack("V4", substr($imageheader, $curoffset));
  38. $curoffset += 16;
  39. print "Segment number $segnum\n";
  40. printf "Load address:\t\t%08x\n", $loadaddr;
  41. printf "Image length:\t\t%d\n", $imagelen;
  42. printf "Memory length:\t\t%d\n", $memlength;
  43. $type = &decodesegmentflags($flags);
  44. printf "Position:\t\t$type\n";
  45. printf "Vendor tag:\t\t%d\n", ($flags >> 8) & 0xff;
  46. if (($vendordata = &getvendordata($flags)) ne '') {
  47. print "Vendor data:\t\t", $vendordata, "\n";
  48. }
  49. print "\n";
  50. push (@seglengths, $imagelen);
  51. return (($flags >> 26) & 1);
  52. }
  53. @seglengths = ();
  54. $#ARGV == 1 or die "Usage: mntnbi tagged-image-file dir\n";
  55. $imagefile= $ARGV[0];
  56. open(I, $ARGV[0]) or die "$imagefile: $!\n";
  57. (defined($status = sysread(I, $imageheader, 512)) and $status == 512)
  58. or die "$imagefile: Cannot read header\n";
  59. $headerrecord = substr($imageheader, 0, 16);
  60. ($magic, $flags, $bx, $ds, $ip, $cs) = unpack("a4Vv4", $headerrecord);
  61. $magic eq "\x36\x13\x03\x1B" or die "$imagefile: Not a tagged image file\n";
  62. $curoffset = 16;
  63. # Now decode the header
  64. printf "Header location:\t%04x:%04x\n", $ds, $bx;
  65. printf "Start address:\t\t%04x:%04x\n", $cs, $ip;
  66. printf "Flags:\n";
  67. print "Return to loader after execution (extension)\n" if (($flags >> 8) & 1);
  68. if (($vendordata = &getvendordata($flags)) ne '') {
  69. print "Vendor data:\t\t", $vendordata, "\n";
  70. }
  71. print "\n";
  72. # Now decode each segment record
  73. $segnum = 1;
  74. do {
  75. $lastrecord = &onesegment($segnum);
  76. ++$segnum;
  77. } while (!$lastrecord);
  78. if ($#seglengths != 1) {
  79. die "This is not a DOS image $#seglengths\n";
  80. }
  81. $offset = 512 + $seglengths[0];
  82. print "mounting filesystem at offset $offset in $ARGV[0] on $ARGV[1]\n";
  83. $rc = system "mount $ARGV[0] $ARGV[1] -t msdos -o loop,offset=$offset";
  84. print "Done\n" if ($rc == 0);
  85. exit(0);