Tuesday, August 14, 2012

Creating a bootable ISO of Windows

When working with VirtualBox or other, a bootable ISO of Windows may be essential.
If not for production, at least for testing or proof-of-concept it can be invaluable.

There may be many tools for achieving this.
I'll document one way to do it from within Solaris 11.
I admit my main reference here was the Linux article :: Linux tune-up :::.

The main hurdle is that not all tools from official suite are present in Solaris 11.
For example, I couldn't find isoinfo which turns out very useful for our goal.

Initially I did't know why FA33 C08E D0BC 007C FB8C had to be searched for.
Would it be exclusive to Windows XP and Windows Server 2003?
Perhaps it would be related to the El Torito standard.
The reasonable answer seems to be here.

This procedure suites slightly modifications or adjustments to a bootable CD too.
I have to say that none of this shall be applicable to Solaris 11 Automated Installer.
Distribution Constructor should be fairly enough for Solaris 11 AI.

Here are the steps that worked for me:

Gather the necessary tools:
 
# pkg install cdrtools
# pkg install hexedit

# pkg install xorriso
  
As a starting point it's necessary to copy the original bootable CD to disk.
For this I have to find out what's the device name of my CD before copying it to disk.
It's important to avoid changes in the original layout of the source tree.
   
# xorriso -devices
GNU xorriso 0.6.0 ...

Beginning to scan for devices ...
Full drive scan done
-
-----------------------------------------------------------
0 -dev '/dev/rdsk/...' r----- : 'HL-DT-ST' 'DVDRAM ...'
------------------------------------------------------------

# dd if=
/dev/rdsk/... of=w2k3.iso bs=2048 conv=noerror,notrunc

# lofiadm -a w2k3.iso/dev/lofi/1
# mount -F hsfs /dev/lofi/1 /mnt
# cp -pPR /mnt w2k3
# umount /mnt
# lofiadm -d /dev/lofi/1
  

Extract an excerpt from the initial part of the CD:
 
# dd if=/dev/rdsk/... of=dump.img bs=2048 count=500
  

Use hexedit in order to look for the boot image.
Once the file is loaded in hexedit (as show below), press Ctrl+S.
Type the search string: FA33C08ED0BC007CFB8C.
Take note of the offset where the search string is found : 00081800.
Quit hexedit with Ctrl-X.
 
# hexedit dump.img
  

Using the found offset, compute the LBA address.
This will indicate from where to begin the boot image extraction:
 

# echo $((16#
81800))530432
# echo $((
530432/2048))
259

# dd if=/dev/rdsk/... of=boot.img bs=2048 count=1 skip=
259
1+0 records in

1+0 records out
 

Copy the extracted boot image into the source tree:
 
# cp boot.img w2k3

   

Finaly, generate the updated ISO filesystem.
The used options' descriptions are as follows:
 
                -v : verbose.
                -V : volume id - used by volcheck to mount under /media.
                -D : preserve layout; put as is.
                -J : add Joliet directory in addition to ISO-9660.
                -d : omit trailing dots  from filenames witn no extension.
                -l : allow long filenames (31 chars).
                -N : no ISO-9660 version number, generally ignored.
-relaxed-filenames : all 7-bit chars beyond lowercase.
 -no-iso-translate : allow # and ~ in filenames.
     -no-emul-boot : load boot image.
   -boot-load-size : 4 sectors of 512 bytes, totaling 2048 bytes.
                -b : boot image.
                -c : boot catalog associated with the boot image.
             -hide : hide from ISO-9660 directory.
      -hide-joliet : hide from Joliet directory, pairing with -hide.
                -o : output (bootable) ISO filesystem.

# mkisofs
  -v
  -V "W2003_ENT_SP1"
  -D -J
  -d -l -N -relaxed-filenames
  -no-iso-translate -no-emul-boot -boot-load-size 4
  -b           boot.img -c           boot.cat
  -hide        boot.img -hide        boot.cat
  -hide-joliet boot.img -hide-joliet boot.cat
  -o w2k3-new.iso
  w2k3

 
Note that boot.cat don't exist and is only declared in the mkisofs command.