6 # geteltorito.pl: a bootimage extractor
7 # Script that will extract the first El Torito bootimage from a
10 # krienke@uni-koblenz.de
13 # Get latest version from:
14 # http://www.uni-koblenz.de/~krienke/ftp/noarch/geteltorito
20 # A patch from Santiago Garcia <manty@debian.org> to use a virtual sector
21 # size (vSecSize) of 512 bytes, as defined on "El Torito" specs and change
22 # unpack of the sector count from n to v to get the correct sector count.
25 # A patch from Ben Collins <bcollins@ubuntu.com> to make the
26 # utility work on PPC machines (change from 'L'-encoding in pack to 'V')
28 # Several patches included from Nathan Stratton Treadway(nathant@ontko.com)
29 # to adjust the platform output as well as fixes for other minor bugs
33 # For information on El Torito see
34 # http://wikipedia.org/
35 # or try this link directly:
36 # http://www.phoenix.com/en/Customer+Services/White+Papers-Specs/Platform+System+Software+Documents/default.htm
40 $ret=undef;$version=undef;$opt_h=undef;$loadSegment=undef;$systemType=undef;
43 # Read a particular sector from a file
44 # sector counting starts at 0, not 1
47 my ($secNum, $secCount, $file)=@_;
50 open(FILE, $file) || die "Cannot open \"$file\" \n";
52 seek(FILE, $secNum*$secSize, 0);
53 $count=read(FILE, $sec, $vSecSize*$secCount, 0) ;
54 if( $count != $vSecSize*$secCount ){
55 warn "Error reading from file \"$file\"\n";
64 # Write eltorito data into a file
70 open(OUT, ">".$name)|| die "$0: Cannot open outputfile \"$name\" for writing. Stop.";
80 warn "\n$0 [-hv] [-o outputfilename] cd-image \n",
81 "Script will try to extract an El Torito image from a \n",
82 "bootable CD (or cd-image) given by <cd-image> and write \n",
83 "the data extracted to STDOUT or to a file.\n",
85 " -v: Print version of script and exit.\n",
86 " -o <file>: Write extracted data to file <file> instead of STDOUT.\n",
92 # ---------------------------------------------------------------------
95 if( defined($opt_v) ){
96 warn "Version: $utilVersion \n";
100 if( defined($opt_h) || $#ARGV <0 ){
104 if( defined($opt_o) ){
105 $outputFilename="$opt_o";
110 if( ! -r $imageFile ){
111 die "Cannot read image/device \"$imageFile\". Aborting\n";
115 # Read Sector 17 from CD which should contain a Boot Record Volume
116 # descriptor. This descriptor contains at its start the text ($isoIdent)
117 # CD001 and ($toritoSpec)
118 # EL TORITO SPECIFICATION
119 # see http://www.cdpage.com/Compact_Disc_Variations/eltoritoi.html
123 $sector=getSector(17, 1, $imageFile );
124 ($boot, $isoIdent, $version, $toritoSpec,
125 $unUsed, $bootP)= unpack( "Ca5CA32A32V", $sector );
127 if( $isoIdent ne "CD001" || $toritoSpec ne "EL TORITO SPECIFICATION" ){
128 die "This data image does not seem to be a bootable CD-image\n";
132 # Now fetch the sector of the booting catalog
134 $sector=getSector($bootP, 1, $imageFile );
136 print STDERR "Booting catalog starts at sector: $bootP \n";
138 # The first 32 bytes of this sector contains the validation entry for a
139 # boot. The first byte has to be 01, the next byte determines the
140 # architecture the image is designed for, where 00 is i86, 01 is PowerPC
141 # and 02 is Mac. More data give info about manufacturer, etc. The
142 # final two bytes must contain 0x55 and 0xAA respectively (as
143 # defined by the El Torito standard).
145 $validateEntry=substr($sector, 0, 32);
147 ($header, $platform, $unUsed, $manufact, $unUsed, $five, $aa)=
148 unpack( "CCvA24vCC", $validateEntry);
150 if( $header != 1 || $five != 0x55 || $aa != 0xaa ){
151 die "Invalid Validation Entry on image \n";
154 print STDERR "Manufacturer of CD: $manufact\n";
155 print STDERR "Image architecture: ";
156 print STDERR "x86" if( $platform == 0 );
157 print STDERR "PowerPC" if( $platform == 1 );
158 print STDERR "Mac" if( $platform == 2 );
159 print STDERR "unknown ($platform)" if( $platform > 2 );
163 # Now we examine the initial/defaultentry which follows the validate
164 # entry and has a size of 32 bytes.
166 $initialEntry=substr($sector, 32, 32);
168 ($boot, $media, $loadSegment, $systemType, $unUsed,
169 $sCount, $imgStart, $unUsed)=unpack( "CCvCCvVC", $initialEntry);
172 die "Boot indicator in Initial/Default-Entry is not 0x88. CD is not bootable. \n";
175 print STDERR "Boot media type is: ";
177 print STDERR "no emulation";
181 print STDERR "1.2meg floppy";
182 $count=1200*1024/$vSecSize;
185 print STDERR "1.44meg floppy";
186 $count=1440*1024/$vSecSize;
189 print STDERR "2.88meg floppy";
190 $count=2880*1024/$vSecSize;
193 print STDERR "harddisk";
198 # Only use the internal sector counter if the real size is unknown
200 $cnt=$count==0?$sCount:$count;
202 print STDERR "El Torito image starts at sector $imgStart and has $cnt sector(s) of $vSecSize Bytes\n";
205 # Now read the bootimage to stdout
206 $image=getSector($imgStart, $cnt, $imageFile);
208 if( length($outputFilename) ){
209 writeOutputFile($outputFilename, $image);
210 print STDERR "\nImage has been written to file \"$outputFilename\".\n";
213 print STDERR "Image has been written to stdout ....\n";