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 33 ed
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
260 90 90 90 90 90 90 90 33 ed fa
8e d5 bc
0 7c fb fc
66 31 db
66 31 c9
66 53
261 66 51 6 57 8e dd
8e c5
52 be
0 7c bf
0 6 b9
0 1 f3 a5 ea
4b
6 0 0 52 b4
41
262 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
263 f1
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
264 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
265 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
266 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
267 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
268 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
269 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
270 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
271 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
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 0 0 0
274 0 0 0 0 0 0 0 0 0 0 0 0 0 0
276 33 ed
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
277 90 90 90 90 90 90 90 33 ed fa
8e d5 bc
0 7c fb fc
66 31 db
66 31 c9
66 53
278 66 51 6 57 8e dd
8e c5 b2
80 52 be
0 7c bf
0 6 b9
0 1 f3 a5 ea
4d
6 0 0 52
279 b4
41 bb aa
55 31 c9
30 f6 f9 cd
13 72 16 81 fb
55 aa
75 10 83 e1
1 74 b
66
280 c7
6 f3
6 b4
42 eb
15 eb
0 5a
51 b4
8 cd
13 83 e1
3f
5b
51 f b6 c6
40 50 f7
281 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
2 e2 f2
282 66 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
283 6c
69 6e
75 78 2e
62 69 6e
20 6d
69 73 73 69 6e
67 20 6f
72 20 63 6f
72 72
284 75 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
285 6a
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
286 e1
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
287 69 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
288 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 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
290 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
291 0 0 0 0 0 0 0 0 0 0 0 0 0
293 33 ed
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
294 90 90 90 90 90 90 90 33 ed fa
8e d5 bc
0 7c fb fc
66 31 db
66 31 c9
66 53
295 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
0 1 f3
296 a5 ea
54 6 0 0 52 b4
41 bb aa
55 31 c9
30 f6 f9 cd
13 72 16 81 fb
55 aa
75
297 10 83 e1
1 74 b
66 c7
6 fa
6 b4
42 eb
15 eb
0 5a
51 b4
8 cd
13 83 e1
3f
5b
298 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
82 80
299 0 66 40 80 c7
2 e2 f2
66 81 3e
40 7c fb c0
78 70 75 9 fa bc ec
7b ea
44 7c
300 0 0 e8
83 0 69 73 6f
6c
69 6e
75 78 2e
62 69 6e
20 6d
69 73 73 69 6e
67 20
301 6f
72 20 63 6f
72 72 75 70 74 2e d a
66 60 66 31 d2
66 3 6 f8
7b
66 13 16
302 fc
7b
66 52 66 50 6 53 6a
1 6a
10 89 e6
66 f7
36 e8
7b c0 e4
6 88 e1
88 c5
303 92 f6
36 ee
7b
88 c6
8 e1
41 b8
1 2 8a
16 f2
7b cd
13 8d
64 10 66 61 c3 e8
304 1e
0 4f
70 65 72 61 74 69 6e
67 20 73 79 73 74 65 6d
20 6c
6f
61 64 20 65
305 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 f4 eb
306 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 0 0 0
307 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
310 33 ed
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
311 90 90 90 90 90 90 90 33 ed fa
8e d5 bc
0 7c fb fc
66 31 db
66 31 c9
21 f6
312 74 26 f6
4 7f
75 21 38 4c
4 74 1c
66 3d
21 47 50 58 75 10 80 7c
4 ed
75 a
313 66 8b
4c
34 66 8b
5c
38 eb
4 66 8b
4c
8 66 53 66 51 6 57 8e dd
8e c5
52 be
314 0 7c bf
0 6 b9
0 1 f3 a5 ea
75 6 0 0 52 b4
41 bb aa
55 31 c9
30 f6 f9 cd
13
315 72 16 81 fb
55 aa
75 10 83 e1
1 74 b
66 c7
6 1b
7 b4
42 eb
15 eb
0 5a
51 b4
316 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 a1 b0
317 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 9 fa
318 bc ec
7b ea
44 7c
0 0 e8
83 0 69 73 6f
6c
69 6e
75 78 2e
62 69 6e
20 6d
69
319 73 73 69 6e
67 20 6f
72 20 63 6f
72 72 75 70 74 2e d a
66 60 66 31 d2
66 3
320 6 f8
7b
66 13 16 fc
7b
66 52 66 50 6 53 6a
1 6a
10 89 e6
66 f7
36 e8
7b c0
321 e4
6 88 e1
88 c5
92 f6
36 ee
7b
88 c6
8 e1
41 b8
1 2 8a
16 f2
7b cd
13 8d
322 64 10 66 61 c3 e8
1e
0 4f
70 65 72 61 74 69 6e
67 20 73 79 73 74 65 6d
20
323 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 3c a
324 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 0 0 0
325 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
327 33 ed
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
328 90 90 90 90 90 90 90 33 ed fa
8e d5 bc
0 7c fb fc
66 31 db
66 31 c9
21 f6
329 74 26 f6
4 7f
75 21 38 4c
4 74 1c
66 3d
21 47 50 58 75 10 80 7c
4 ed
75 a
330 66 8b
4c
34 66 8b
5c
38 eb
4 66 8b
4c
8 66 53 66 51 6 57 8e dd
8e c5 b2
80
331 52 be
0 7c bf
0 6 b9
0 1 f3 a5 ea
77 6 0 0 52 b4
41 bb aa
55 31 c9
30 f6 f9
332 cd
13 72 16 81 fb
55 aa
75 10 83 e1
1 74 b
66 c7
6 1d
7 b4
42 eb
15 eb
0 5a
333 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
334 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
335 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
336 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
337 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
338 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
339 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
340 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
341 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
342 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
344 33 ed
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
345 90 90 90 90 90 90 90 33 ed fa
8e d5 bc
0 7c fb fc
66 31 db
66 31 c9
21 f6
346 74 26 f6
4 7f
75 21 38 4c
4 74 1c
66 3d
21 47 50 58 75 10 80 7c
4 ed
75 a
347 66 8b
4c
34 66 8b
5c
38 eb
4 66 8b
4c
8 66 53 66 51 6 57 8e dd
8e c5 f6
6
348 17 4 4 74 2 b2
80 52 be
0 7c bf
0 6 b9
0 1 f3 a5 ea
7e
6 0 0 52 b4
41 bb aa
349 55 31 c9
30 f6 f9 cd
13 72 16 81 fb
55 aa
75 10 83 e1
1 74 b
66 c7
6 24 7
350 b4
42 eb
15 eb
0 5a
51 b4
8 cd
13 83 e1
3f
5b
51 f b6 c6
40 50 f7 e1
53 52
351 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 81 3e
352 40 7c fb c0
78 70 75 9 fa bc ec
7b ea
44 7c
0 0 e8
83 0 69 73 6f
6c
69 6e
353 75 78 2e
62 69 6e
20 6d
69 73 73 69 6e
67 20 6f
72 20 63 6f
72 72 75 70 74
354 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
1 6a
355 10 89 e6
66 f7
36 e8
7b c0 e4
6 88 e1
88 c5
92 f6
36 ee
7b
88 c6
8 e1
41 b8
356 1 2 8a
16 f2
7b cd
13 8d
64 10 66 61 c3 e8
1e
0 4f
70 65 72 61 74 69 6e
67
357 20 73 79 73 74 65 6d
20 6c
6f
61 64 20 65 72 72 6f
72 2e d a
5e ac b4 e
8a
358 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 0 0 0
359 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