2014-01-21 12:47:57 +04:00
|
|
|
#!/usr/bin/perl
|
|
|
|
|
|
|
|
use strict;
|
|
|
|
use warnings;
|
|
|
|
|
|
|
|
use Fcntl ':seek';
|
|
|
|
|
|
|
|
if (scalar(@ARGV) < 1) {
|
|
|
|
print "Usage: $0 iso-image-file\n";
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
my $filename = $ARGV[0];
|
|
|
|
my $file;
|
|
|
|
open($file, '+<', $filename) or die "Failed to open file $filename for read-write: $!";
|
|
|
|
binmode($file);
|
|
|
|
|
|
|
|
# Read the first sector (512 bytes) containing the MBR
|
|
|
|
my $mbr;
|
|
|
|
read($file, $mbr, 512) or die "Failed to read the MBR sector: $!";
|
|
|
|
|
|
|
|
# Extract the second partition record from the MBR (except for the "bootable" flag)
|
|
|
|
my $partition2 = substr($mbr, 463, 15);
|
|
|
|
|
|
|
|
# In 32-bit images we don't have the second partition (EFI), so here we'll create
|
|
|
|
# a fake partition without actual file system.
|
|
|
|
if ($partition2 eq ("\x00" x 15)) {
|
|
|
|
# Partition recod
|
2014-01-21 16:50:27 +04:00
|
|
|
$partition2 = "\x00\x02\x00" . # CHS: first sector = 2
|
2014-01-21 12:47:57 +04:00
|
|
|
"\xDA" . # partition type: non-filesystem data
|
|
|
|
"\x00\x02\x00" . # CHS: last sector = 2
|
|
|
|
"\x01\x00\x00\x00" . # LBA: first sector = 1
|
|
|
|
"\x01\x00\x00\x00"; # LBA: number of sectors = 1
|
|
|
|
}
|
|
|
|
|
|
|
|
# Now write back the desired partition table into MBR.
|
|
|
|
# The partition table starts at offset 446 and contains 4 records 16 bytes each. What we do:
|
|
|
|
# 1) Replace the first record with the second one (real or faked for 32-bit images);
|
|
|
|
# 2) Replace the first byte of the resulting first record with 0x80 (mark partition as active);
|
|
|
|
# 3) Delete the second partition by zeroing its contents.
|
|
|
|
substr($mbr, 446, 32) = "\x80" . $partition2 . ("\x00" x 16);
|
|
|
|
|
|
|
|
# Write the updated MBR back
|
|
|
|
seek($file, 0, SEEK_SET) or die "Failed to position at the beginning of the file: $!";
|
|
|
|
print $file $mbr;
|
|
|
|
close($file);
|