From aee4e8fa73571eaca80ad43aa007523cde5d4567 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 20 May 2009 19:06:42 -0700 Subject: [PATCH] isohybrid: add options, change default ptype to 0x17 Add support for setting a variety of options in isohybrid. Also change the default partition type to 0x17, "Windows hidden IFS", as that seems to make Windows less unhappy. Signed-off-by: H. Peter Anvin --- NEWS | 1 + utils/isohybrid.in | 94 ++++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 82 insertions(+), 13 deletions(-) diff --git a/NEWS b/NEWS index d753563..6518456 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,7 @@ Changes in 3.81: new "NOHALT 1" configuration command. * linux.c32 now suppresses all messages if the "quiet" flag is specified. + * isohybrid: add a variety of options, and a help message. Changes in 3.80: * New shuffler mechanism and API. diff --git a/utils/isohybrid.in b/utils/isohybrid.in index 83f9dc0..61ff795 100644 --- a/utils/isohybrid.in +++ b/utils/isohybrid.in @@ -19,8 +19,47 @@ use bytes; use Fcntl; -# Use this fake geometry (zipdrive-style...) -$h = 64; $s = 32; +# User-specifyable options +%opt = ( + # Fake geometry (zipdrive-style...) + 'h' => 64, + 's' => 32, + # Partition number + 'entry' => 1, + # Partition offset + 'offset' => 0, + # Partition type + 'type' => 0x17, # "Windows hidden IFS" + # MBR ID + 'id' => undef, +); + +%valid_range = ( + 'h' => [1, 256], + 's' => [1, 63], + 'entry' => [1, 4], + 'offset' => [0, 64], + 'type' => [0, 255], + 'id' => [0, 0xffffffff], +); + +sub usage() { + print STDERR "Usage: $0 [options] filename\n", + "Options:\n", + " -h Number of default geometry heads\n", + " -s Number of default geometry sectors\n", + " -entry Specify partition entry number (1-4)\n", + " -offset Specify partition offset (default 0)\n", + " -type Specify partition type (default 0x17)\n", + " -id Specify MBR ID (default random)\n"; + exit 1; +} + +# Parse a C-style integer (decimal/octal/hex) +sub doh($) { + my($n) = @_; + return ($n =~ /^0/) ? oct $n : $n+0; +} sub get_random() { # Get a 32-bit random number @@ -38,8 +77,28 @@ sub get_random() { return ($$+time()) & 0xffffffff; } +while ($ARGV[0] =~ /^\-(.*)$/) { + $o = $1; + shift @ARGV; + if (exists($opt{$o})) { + $opt{$o} = doh(shift @ARGV); + if (defined($valid_range{$o})) { + ($l, $h) = @{$valid_range{$o}}; + if ($opt{$o} < $l || $opt{$o} > $h) { + die "$0: valid values for the -$o parameter are $l to $h\n"; + } + } + } else { + usage(); + } +} ($file) = @ARGV; + +if (!defined($file)) { + usage(); +} + open(FILE, "+< $file\0") or die "$0: cannot open $file: $!\n"; binmode FILE; @@ -87,6 +146,8 @@ if (!$imgsize) { die "$0: $file: cannot determine length of file\n"; } # Target image size: round up to a multiple of $h*$s*512 +$h = $opt{'h'}; +$s = $opt{'s'}; $cylsize = $h*$s*512; $frac = $imgsize % $cylsize; $padding = ($frac > 0) ? $cylsize - $frac : 0; @@ -101,10 +162,14 @@ if ($c > 1024) { } # Preserve id when run again -seek(FILE, 440, SEEK_SET) or die "$0: $file: $!\n"; -read(FILE, $id, 4); -if ($id eq "\x00\x00\x00\x00") { - $id = pack("V", get_random()); +if (defined($opt{'id'})) { + $id = $opt{'id'}; +} else { + seek(FILE, 440, SEEK_SET) or die "$0: $file: $!\n"; + read(FILE, $id, 4); + if ($id eq "\x00\x00\x00\x00") { + $id = pack("V", get_random()); + } } # Print the MBR and partition table @@ -123,20 +188,23 @@ if ( length($mbr) > 432 ) { $mbr .= "\0" x (432 - length($mbr)); -$mbr .= pack("VV", $de_lba*4, 0); # Offset 432: LBA of isolinux.bin +$mbr .= pack("VV", $de_lba*4, 0); # Offset 432: LBA of isolinux.bin $mbr .= $id; # Offset 440: MBR ID -$mbr .= "\0\0"; # Offset 446: actual partition table +$mbr .= "\0\0"; # Offset 446: actual partition table # Print partition table +$offset = $opt{'offset'}; $psize = $c*$h*$s; -$bhead = 0; -$bsect = 1; -$bcyl = 0; +$bhead = int($offset/$s) % $h; +$bsect = ($offset % $s) + 1; +$bcyl = int($offset/($h*$s)); +$bsect += ($bcyl & 0x300) >> 2; +$bcyl &= 0xff; $ehead = $h-1; $esect = $s + ((($cc-1) & 0x300) >> 2); $ecyl = ($cc-1) & 0xff; -$fstype = 0x83; # Linux (any better ideas?) -$pentry = 1; # First partition slot +$fstype = $opt{'type'}; # Partition type +$pentry = $opt{'entry'}; # Partition slot for ( $i = 1 ; $i <= 4 ; $i++ ) { if ( $i == $pentry ) { -- 2.7.4