2 ## -----------------------------------------------------------------------
4 ## Copyright 2002-2008 H. Peter Anvin - All Rights Reserved
5 ## Copyright 2009 Intel Corporation; author: H. Peter Anvin
7 ## This program is free software; you can redistribute it and/or modify
8 ## it under the terms of the GNU General Public License as published by
9 ## the Free Software Foundation, Inc., 53 Temple Place Ste 330,
10 ## Boston MA 02111-1307, USA; either version 2 of the License, or
11 ## (at your option) any later version; incorporated herein by reference.
13 ## -----------------------------------------------------------------------
16 # Post-process an ISO 9660 image generated with mkisofs/genisoimage
17 # to allow "hybrid booting" as a CD-ROM or as a hard disk.
23 # User-specifyable options
25 # Fake geometry (zipdrive-style...)
33 'type' => 0x17, # "Windows hidden IFS"
44 'id' => [0, 0xffffffff],
49 # Boolean options just set other options
51 'nohd0' => ['hd0', 0],
52 'forcehd0' => ['hd0', 1],
53 'ctrlhd0' => ['hd0', 2],
54 'nopartok' => ['partok', 0],
55 'partok' => ['partok', 1],
59 print STDERR
"Usage: $0 [options] filename.iso\n",
61 " -h Number of default geometry heads\n",
62 " -s Number of default geometry sectors\n",
63 " -entry Specify partition entry number (1-4)\n",
64 " -offset Specify partition offset (default 0)\n",
65 " -type Specify partition type (default 0x17)\n",
66 " -id Specify MBR ID (default random)\n",
67 " -forcehd0 Always assume we are loaded as disk ID 0\n",
68 " -ctrlhd0 Assume disk ID 0 if the Ctrl key is pressed\n",
69 " -partok Allow booting from within a partition\n";
73 # Parse a C-style integer (decimal/octal/hex)
76 return ($n =~ /^0/) ?
oct $n : $n+0;
80 # Get a 32-bit random number
84 if (open($rfd, "< /dev/urandom\0") && read($rfd, $rnd, 4) == 4) {
85 $rid = unpack("V", $rnd);
88 close($rfd) if (defined($rfd));
89 return $rid if (defined($rid));
91 # This sucks but is better than nothing...
92 return ($$+time()) & 0xffffffff;
98 while ( $line = <DATA
> ) {
100 last if ($line eq '*');
101 foreach $byte ( split(/\s+/, $line) ) {
102 $mbr .= chr(hex($byte));
108 while ($ARGV[0] =~ /^\-(.*)$/) {
111 if (defined($bool_opt{$o})) {
112 ($o, $v) = @
{$bool_opt{$o}};
114 } elsif (exists($opt{$o})) {
115 $opt{$o} = doh
(shift @ARGV);
116 if (defined($valid_range{$o})) {
117 ($l, $h) = @
{$valid_range{$o}};
118 if ($opt{$o} < $l || $opt{$o} > $h) {
119 die "$0: valid values for the -$o parameter are $l to $h\n";
129 if (!defined($file)) {
133 open(FILE
, "+< $file\0") or die "$0: cannot open $file: $!\n";
137 # First, actually figure out where mkisofs hid isolinux.bin
139 seek(FILE
, 17*2048, SEEK_SET
) or die "$0: $file: $!\n";
140 read(FILE
, $boot_record, 2048) == 2048 or die "$0: $file: read error\n";
141 ($br_sign, $br_cat_offset) = unpack("a71V", $boot_record);
142 if ($br_sign ne ("\0CD001\1EL TORITO SPECIFICATION" . ("\0" x
41))) {
143 die "$0: $file: no boot record found\n";
145 seek(FILE
, $br_cat_offset*2048, SEEK_SET
) or die "$0: $file: $!\n";
146 read(FILE
, $boot_cat, 2048) == 2048 or die "$0: $file: read error\n";
148 # We must have a Validation Entry followed by a Default Entry...
149 # no fanciness allowed for the Hybrid mode [XXX: might relax this later]
150 @ve = unpack("v16", $boot_cat);
152 for ($i = 0; $i < 16; $i++) {
155 if ($ve[0] != 0x0001 || $ve[15] != 0xaa55 || $cs & 0xffff) {
156 die "$0: $file: invalid boot catalog\n";
158 ($de_boot, $de_media, $de_seg, $de_sys, $de_mbz1, $de_count,
159 $de_lba, $de_mbz2) = unpack("CCvCCvVv", substr($boot_cat, 32, 32));
160 if ($de_boot != 0x88 || $de_media != 0 ||
161 ($de_segment != 0 && $de_segment != 0x7c0) || $de_count != 4) {
162 die "$0: $file: unexpected boot catalog parameters\n";
165 # Now $de_lba should contain the CD sector number for isolinux.bin
166 seek(FILE
, $de_lba*2048+0x40, SEEK_SET
) or die "$0: $file: $!\n";
167 read(FILE
, $ibsig, 4);
168 if ($ibsig ne "\xfb\xc0\x78\x70") {
169 die "$0: $file: bootloader does not have a isolinux.bin hybrid signature.".
170 "Note that isolinux-debug.bin does not support hybrid booting.\n";
173 # Get the total size of the image
174 (@imgstat = stat(FILE
)) or die "$0: $file: $!\n";
175 $imgsize = $imgstat[7];
177 die "$0: $file: cannot determine length of file\n";
179 # Target image size: round up to a multiple of $h*$s*512
182 $cylsize = $h*$s*512;
183 $frac = $imgsize % $cylsize;
184 $padding = ($frac > 0) ?
$cylsize - $frac : 0;
185 $imgsize += $padding;
186 $c = int($imgsize/$cylsize);
188 print STDERR
"Warning: more than 1024 cylinders ($c).\n";
189 print STDERR
"Not all BIOSes will be able to boot this device.\n";
195 # Preserve id when run again
196 if (defined($opt{'id'})) {
197 $id = pack("V", doh
($opt{'id'}));
199 seek(FILE
, 440, SEEK_SET
) or die "$0: $file: $!\n";
201 if ($id eq "\x00\x00\x00\x00") {
202 $id = pack("V", get_random
());
206 # Print the MBR and partition table
207 seek(FILE
, 0, SEEK_SET
) or die "$0: $file: $!\n";
209 for ($i = 0; $i <= $opt{'hd0'}+3*$opt{'partok'}; $i++) {
210 $mbr = get_hex_data
();
212 if ( length($mbr) > 432 ) {
213 die "$0: Bad MBR code\n";
216 $mbr .= "\0" x
(432 - length($mbr));
218 $mbr .= pack("VV", $de_lba*4, 0); # Offset 432: LBA of isolinux.bin
219 $mbr .= $id; # Offset 440: MBR ID
220 $mbr .= "\0\0"; # Offset 446: actual partition table
222 # Print partition table
223 $offset = $opt{'offset'};
224 $psize = $c*$h*$s - $offset;
225 $bhead = int($offset/$s) % $h;
226 $bsect = ($offset % $s) + 1;
227 $bcyl = int($offset/($h*$s));
228 $bsect += ($bcyl & 0x300) >> 2;
231 $esect = $s + ((($cc-1) & 0x300) >> 2);
232 $ecyl = ($cc-1) & 0xff;
233 $fstype = $opt{'type'}; # Partition type
234 $pentry = $opt{'entry'}; # Partition slot
236 for ( $i = 1 ; $i <= 4 ; $i++ ) {
237 if ( $i == $pentry ) {
238 $mbr .= pack("CCCCCCCCVV", 0x80, $bhead, $bsect, $bcyl, $fstype,
239 $ehead, $esect, $ecyl, $offset, $psize);
248 # Pad the image to a fake cylinder boundary
249 seek(FILE
, $imgstat[7], SEEK_SET
) or die "$0: $file: $!\n";
251 print FILE
"\0" x
$padding;
259 fa
31 ed
8e d5 bc
0 7c fb fc
66 31 db
66 31 c9
66 53 66 51 6 57 8e dd
8e c5
260 52 be
0 7c bf
0 6 b9
0 1 f3 a5 ea
2b
6 0 0 52 b4
41 bb aa
55 31 c9
30 f6 f9
261 cd
13 72 16 81 fb
55 aa
75 10 83 e1
1 74 b
66 c7
6 d1
6 b4
42 eb
15 eb
0 5a
262 51 b4
8 cd
13 83 e1
3f
5b
51 f b6 c6
40 50 f7 e1
53 52 50 bb
0 7c b9
4 0 66
263 a1 b0
7 e8
44 0 f
82 80 0 66 40 80 c7
2 e2 f2
66 81 3e
40 7c fb c0
78 70 75
264 9 fa bc ec
7b ea
44 7c
0 0 e8
83 0 69 73 6f
6c
69 6e
75 78 2e
62 69 6e
20
265 6d
69 73 73 69 6e
67 20 6f
72 20 63 6f
72 72 75 70 74 2e d a
66 60 66 31 d2
266 66 3 6 f8
7b
66 13 16 fc
7b
66 52 66 50 6 53 6a
1 6a
10 89 e6
66 f7
36 e8
267 7b c0 e4
6 88 e1
88 c5
92 f6
36 ee
7b
88 c6
8 e1
41 b8
1 2 8a
16 f2
7b cd
268 13 8d
64 10 66 61 c3 e8
1e
0 4f
70 65 72 61 74 69 6e
67 20 73 79 73 74 65
269 6d
20 6c
6f
61 64 20 65 72 72 6f
72 2e d a
5e ac b4 e
8a
3e
62 4 b3
7 cd
10
270 3c a
75 f1 cd
18 f4 eb fd
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
271 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
272 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
273 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
275 fa
31 ed
8e d5 bc
0 7c fb fc
66 31 db
66 31 c9
66 53 66 51 6 57 8e dd
8e c5
276 b2
80 52 be
0 7c bf
0 6 b9
0 1 f3 a5 ea
2d
6 0 0 52 b4
41 bb aa
55 31 c9
30
277 f6 f9 cd
13 72 16 81 fb
55 aa
75 10 83 e1
1 74 b
66 c7
6 d3
6 b4
42 eb
15
278 eb
0 5a
51 b4
8 cd
13 83 e1
3f
5b
51 f b6 c6
40 50 f7 e1
53 52 50 bb
0 7c
279 b9
4 0 66 a1 b0
7 e8
44 0 f
82 80 0 66 40 80 c7
2 e2 f2
66 81 3e
40 7c fb
280 c0
78 70 75 9 fa bc ec
7b ea
44 7c
0 0 e8
83 0 69 73 6f
6c
69 6e
75 78 2e
281 62 69 6e
20 6d
69 73 73 69 6e
67 20 6f
72 20 63 6f
72 72 75 70 74 2e d a
66
282 60 66 31 d2
66 3 6 f8
7b
66 13 16 fc
7b
66 52 66 50 6 53 6a
1 6a
10 89 e6
283 66 f7
36 e8
7b c0 e4
6 88 e1
88 c5
92 f6
36 ee
7b
88 c6
8 e1
41 b8
1 2 8a
284 16 f2
7b cd
13 8d
64 10 66 61 c3 e8
1e
0 4f
70 65 72 61 74 69 6e
67 20 73
285 79 73 74 65 6d
20 6c
6f
61 64 20 65 72 72 6f
72 2e d a
5e ac b4 e
8a
3e
62
286 4 b3
7 cd
10 3c a
75 f1 cd
18 f4 eb fd
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
287 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
288 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
289 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
292 fa
31 ed
8e d5 bc
0 7c fb fc
66 31 db
66 31 c9
66 53 66 51 6 57 8e dd
8e c5
293 f6
6 17 4 4 74 2 b2
80 52 be
0 7c bf
0 6 b9
0 1 f3 a5 ea
34 6 0 0 52 b4
41
294 bb aa
55 31 c9
30 f6 f9 cd
13 72 16 81 fb
55 aa
75 10 83 e1
1 74 b
66 c7
6
295 da
6 b4
42 eb
15 eb
0 5a
51 b4
8 cd
13 83 e1
3f
5b
51 f b6 c6
40 50 f7 e1
296 53 52 50 bb
0 7c b9
4 0 66 a1 b0
7 e8
44 0 f
82 80 0 66 40 80 c7
2 e2 f2
66
297 81 3e
40 7c fb c0
78 70 75 9 fa bc ec
7b ea
44 7c
0 0 e8
83 0 69 73 6f
6c
298 69 6e
75 78 2e
62 69 6e
20 6d
69 73 73 69 6e
67 20 6f
72 20 63 6f
72 72 75
299 70 74 2e d a
66 60 66 31 d2
66 3 6 f8
7b
66 13 16 fc
7b
66 52 66 50 6 53 6a
300 1 6a
10 89 e6
66 f7
36 e8
7b c0 e4
6 88 e1
88 c5
92 f6
36 ee
7b
88 c6
8 e1
301 41 b8
1 2 8a
16 f2
7b cd
13 8d
64 10 66 61 c3 e8
1e
0 4f
70 65 72 61 74 69
302 6e
67 20 73 79 73 74 65 6d
20 6c
6f
61 64 20 65 72 72 6f
72 2e d a
5e ac b4
303 e
8a
3e
62 4 b3
7 cd
10 3c a
75 f1 cd
18 f4 eb fd
0 0 0 0 0 0 0 0 0 0 0 0
304 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
305 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
306 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
308 fa
31 ed
8e d5 bc
0 7c fb fc
66 31 db
66 31 c9
21 f6
74 21 f6
4 7f
75 1c
66
309 3d
21 47 50 58 75 10 80 7c
4 ee
75 a
66 8b
4c
30 66 8b
5c
34 eb
4 66 8b
4c
310 8 66 53 66 51 6 57 8e dd
8e c5
52 be
0 7c bf
0 6 b9
0 1 f3 a5 ea
50 6 0 0
311 52 b4
41 bb aa
55 31 c9
30 f6 f9 cd
13 72 16 81 fb
55 aa
75 10 83 e1
1 74
312 b
66 c7
6 f6
6 b4
42 eb
15 eb
0 5a
51 b4
8 cd
13 83 e1
3f
5b
51 f b6 c6
40
313 50 f7 e1
53 52 50 bb
0 7c b9
4 0 66 a1 b0
7 e8
44 0 f
82 80 0 66 40 80 c7
314 2 e2 f2
66 81 3e
40 7c fb c0
78 70 75 9 fa bc ec
7b ea
44 7c
0 0 e8
83 0 69
315 73 6f
6c
69 6e
75 78 2e
62 69 6e
20 6d
69 73 73 69 6e
67 20 6f
72 20 63 6f
316 72 72 75 70 74 2e d a
66 60 66 31 d2
66 3 6 f8
7b
66 13 16 fc
7b
66 52 66
317 50 6 53 6a
1 6a
10 89 e6
66 f7
36 e8
7b c0 e4
6 88 e1
88 c5
92 f6
36 ee
7b
318 88 c6
8 e1
41 b8
1 2 8a
16 f2
7b cd
13 8d
64 10 66 61 c3 e8
1e
0 4f
70 65
319 72 61 74 69 6e
67 20 73 79 73 74 65 6d
20 6c
6f
61 64 20 65 72 72 6f
72 2e
320 d a
5e ac b4 e
8a
3e
62 4 b3
7 cd
10 3c a
75 f1 cd
18 f4 eb fd
0 0 0 0 0 0
321 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
322 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
323 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
325 fa
31 ed
8e d5 bc
0 7c fb fc
66 31 db
66 31 c9
21 f6
74 21 f6
4 7f
75 1c
66
326 3d
21 47 50 58 75 10 80 7c
4 ee
75 a
66 8b
4c
30 66 8b
5c
34 eb
4 66 8b
4c
327 8 66 53 66 51 6 57 8e dd
8e c5 b2
80 52 be
0 7c bf
0 6 b9
0 1 f3 a5 ea
52
328 6 0 0 52 b4
41 bb aa
55 31 c9
30 f6 f9 cd
13 72 16 81 fb
55 aa
75 10 83 e1
329 1 74 b
66 c7
6 f8
6 b4
42 eb
15 eb
0 5a
51 b4
8 cd
13 83 e1
3f
5b
51 f b6
330 c6
40 50 f7 e1
53 52 50 bb
0 7c b9
4 0 66 a1 b0
7 e8
44 0 f
82 80 0 66 40
331 80 c7
2 e2 f2
66 81 3e
40 7c fb c0
78 70 75 9 fa bc ec
7b ea
44 7c
0 0 e8
332 83 0 69 73 6f
6c
69 6e
75 78 2e
62 69 6e
20 6d
69 73 73 69 6e
67 20 6f
72
333 20 63 6f
72 72 75 70 74 2e d a
66 60 66 31 d2
66 3 6 f8
7b
66 13 16 fc
7b
334 66 52 66 50 6 53 6a
1 6a
10 89 e6
66 f7
36 e8
7b c0 e4
6 88 e1
88 c5
92 f6
335 36 ee
7b
88 c6
8 e1
41 b8
1 2 8a
16 f2
7b cd
13 8d
64 10 66 61 c3 e8
1e
0
336 4f
70 65 72 61 74 69 6e
67 20 73 79 73 74 65 6d
20 6c
6f
61 64 20 65 72 72
337 6f
72 2e d a
5e ac b4 e
8a
3e
62 4 b3
7 cd
10 3c a
75 f1 cd
18 f4 eb fd
0
338 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
339 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
340 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
342 fa
31 ed
8e d5 bc
0 7c fb fc
66 31 db
66 31 c9
21 f6
74 21 f6
4 7f
75 1c
66
343 3d
21 47 50 58 75 10 80 7c
4 ee
75 a
66 8b
4c
30 66 8b
5c
34 eb
4 66 8b
4c
344 8 66 53 66 51 6 57 8e dd
8e c5 f6
6 17 4 4 74 2 b2
80 52 be
0 7c bf
0 6 b9
345 0 1 f3 a5 ea
59 6 0 0 52 b4
41 bb aa
55 31 c9
30 f6 f9 cd
13 72 16 81 fb
55
346 aa
75 10 83 e1
1 74 b
66 c7
6 ff
6 b4
42 eb
15 eb
0 5a
51 b4
8 cd
13 83 e1
347 3f
5b
51 f b6 c6
40 50 f7 e1
53 52 50 bb
0 7c b9
4 0 66 a1 b0
7 e8
44 0 f
348 82 80 0 66 40 80 c7
2 e2 f2
66 81 3e
40 7c fb c0
78 70 75 9 fa bc ec
7b ea
349 44 7c
0 0 e8
83 0 69 73 6f
6c
69 6e
75 78 2e
62 69 6e
20 6d
69 73 73 69 6e
350 67 20 6f
72 20 63 6f
72 72 75 70 74 2e d a
66 60 66 31 d2
66 3 6 f8
7b
66
351 13 16 fc
7b
66 52 66 50 6 53 6a
1 6a
10 89 e6
66 f7
36 e8
7b c0 e4
6 88 e1
352 88 c5
92 f6
36 ee
7b
88 c6
8 e1
41 b8
1 2 8a
16 f2
7b cd
13 8d
64 10 66 61
353 c3 e8
1e
0 4f
70 65 72 61 74 69 6e
67 20 73 79 73 74 65 6d
20 6c
6f
61 64
354 20 65 72 72 6f
72 2e d a
5e ac b4 e
8a
3e
62 4 b3
7 cd
10 3c a
75 f1 cd
18
355 f4 eb fd
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
356 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
357 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0