home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / boot / i386 / root / usr / lib / YaST2 / bin / tp_mbr < prev    next >
Text File  |  2006-11-29  |  4KB  |  123 lines

  1. #! /usr/bin/perl
  2.  
  3. #
  4. # Install MBR on Thinkpads.
  5. #
  6. # TPs have a special boot loader to manage the rescue stuff. It keeps the
  7. # orignal MBR stored somewhere and uses it to boot the normal OSes.
  8. #
  9. # MBR[6]: 1 byte CRC over original MBR
  10. # MBR[7]: sector number of original MBR
  11. #
  12.  
  13. sub crc;
  14.  
  15. # mbr from master-boot-code package
  16. $new_mbr =
  17.   "\x31\xc0\x8e\xd0\x66\xbc\x00\x7c\x00\x00\x8e\xc0\x8e\xd8\x89\xe6" .
  18.   "\x66\xbf\x00\x06\x00\x00\x66\xb9\x00\x01\x00\x00\xf3\xa5\xea\x23" .
  19.   "\x06\x00\x00\x80\xfa\x80\x7c\x05\x80\xfa\x87\x7e\x02\xb2\x80\x88" .
  20.   "\x16\x49\x07\x66\xbf\xbe\x07\x00\x00\x31\xf6\x66\xb9\x04\x00\x00" .
  21.   "\x00\x67\x80\x3f\x80\x75\x07\x85\xf6\x75\x0c\x66\x89\xfe\x83\xc7" .
  22.   "\x10\xe2\xee\x85\xf6\x75\x0b\x66\xbe\x4a\x07\x00\x00\xe9\x8d\x00" .
  23.   "\x00\x00\x8a\x16\x49\x07\x66\x31\xc9\x66\x31\xc0\xb4\x08\xcd\x13" .
  24.   "\xc1\xea\x08\x42\x89\xc8\x83\xe0\x3f\x89\xcb\xc1\xe9\x08\x81\xe3" .
  25.   "\xc0\x00\x00\x00\xc1\xe3\x02\x09\xd9\x41\xf7\xe2\x66\xf7\xe1\x8a" .
  26.   "\x16\x49\x07\x66\x67\x8b\x5e\x08\x66\x39\xc3\x66\x7c\x63\x66\x56" .
  27.   "\x52\x66\xbb\xaa\x55\x00\x00\xb4\x41\xcd\x13\x5a\x66\x5e\x72\x51" .
  28.   "\x66\xb8\x55\xaa\x00\x00\x39\xc3\x75\x47\xf6\xc1\x01\x74\x42\x67" .
  29.   "\x66\xc7\x06\x10\x00\x01\x00\x67\x66\xc7\x46\x04\x00\x7c\x00\x00" .
  30.   "\x67\x66\xc7\x46\x0c\x00\x00\x00\x00\xb6\x05\x56\x52\xb4\x42\xcd" .
  31.   "\x13\x5a\x5e\x73\x45\xfe\xce\x75\xf2\x66\xbe\x76\x07\x00\x00\xac" .
  32.   "\x84\xc0\x74\x0a\xb4\x0e\xb3\x07\x56\xcd\x10\x5e\xeb\xf1\xfb\xeb" .
  33.   "\xfd\x67\x8a\x76\x01\x67\x8b\x4e\x02\x66\xbf\x05\x00\x00\x00\x66" .
  34.   "\xbb\x00\x7c\x00\x00\x66\xb8\x01\x02\x00\x00\x57\x52\x51\xcd\x13" .
  35.   "\x59\x5a\x5f\x73\x05\x4f\x75\xe7\xeb\xbf\x66\xbe\x62\x07\x00\x00" .
  36.   "\x67\xa1\xfe\x7d\x00\x00\x66\xbb\x55\xaa\x00\x00\x39\xc3\x75\xaf" .
  37.   "\x8a\x16\x49\x07\xea\x00\x7c\x00\x00\x80\x49\x6e\x76\x61\x6c\x69" .
  38.   "\x64\x20\x70\x61\x72\x74\x69\x74\x69\x6f\x6e\x20\x74\x61\x62\x6c" .
  39.   "\x65\x00\x4e\x6f\x20\x6f\x70\x65\x72\x61\x74\x69\x6e\x67\x20\x73" .
  40.   "\x79\x73\x74\x65\x6d\x00\x45\x72\x72\x6f\x72\x20\x6c\x6f\x61\x64" .
  41.   "\x69\x6e\x67\x20\x6f\x70\x65\x72\x61\x74\x69\x6e\x67\x20\x73\x79" .
  42.   "\x73\x74\x65\x6d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
  43.   "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
  44.   "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
  45.  
  46.  
  47. $disk = shift;
  48.  
  49. die "usage: tp_mbr device\n" unless $disk && (-f($disk) || -b($disk));
  50.  
  51. open F, $disk;
  52. sysread F, $mbr, 0x200;
  53.  
  54. @mbr = unpack "C512", $mbr;
  55.  
  56. die "$disk: no mbr\n" unless @mbr == 0x200 && $mbr[0x1fe] == 0x55 && $mbr[0x1ff] == 0xaa;
  57.  
  58. $old_mbr_sec = $mbr[7];
  59.  
  60. # just a quick check
  61. die "$disk: np tp mbr\n" unless
  62.   $mbr[0x17b] == 0x50 &&
  63.   $mbr[0x17c] == 0xe4 &&
  64.   $mbr[0x17d] == 0x61 &&
  65.   $mbr[0x17e] == 0x24 &&
  66.   $old_mbr_sec > 1;
  67.  
  68.  
  69. # read original mbr
  70.  
  71. seek F, ($old_mbr_sec - 1) << 9, 0 or die "$disk: $!\n";
  72.  
  73. sysread F, $old_mbr, 0x200;
  74.  
  75. @old_mbr = unpack "C512", $old_mbr;
  76.  
  77. die "$disk: no orig mbr\n" unless @old_mbr == 0x200 && $old_mbr[0x1fe] == 0x55 && $mbr[0x1ff] == 0xaa;
  78.  
  79. close F;
  80.  
  81.  
  82. # verify crc
  83.  
  84. if($mbr[6] == 0) {
  85.   print STDERR "$disk: orig mbr crc not checked\n" if $mbr[6] == 0;
  86. }
  87. else {
  88.   die "$disk: orig mbr crc failure\n" unless crc(\@old_mbr) == $mbr[6];
  89. }
  90.  
  91.  
  92. # store new mbr & update crc
  93.  
  94. substr($old_mbr, 0, length $new_mbr) = $new_mbr;
  95.  
  96. @old_mbr = unpack "C512", $old_mbr;
  97.  
  98. $mbr[6] = crc \@old_mbr;
  99.  
  100. $mbr = pack "C512", @mbr;
  101.  
  102.  
  103. # write it
  104.  
  105. open F, "+<$disk";
  106. syswrite F, $mbr, 0x200;
  107. seek F, ($old_mbr_sec - 1) << 9, 0;
  108. syswrite F, $old_mbr;
  109. close F;
  110.  
  111.  
  112. # crc function
  113. sub crc
  114. {
  115.   my $c = 0;
  116.   local $_;
  117.  
  118.   $c ^= $_ for @{$_[0]};
  119.  
  120.   return $c;
  121. }
  122.  
  123.