Jan 16 2008

Multi-OS Installation: Configuring the Windows Image – Part 2

Continuing from where we left off in Part 1. In the /export/install/images/W51AA directory there are several directories: boot, i386, inf, amd64, and sys. The directories contain the following:

boot/ – the collection of bootloader files and the sif file.

inf/ – the driver information files. The contents of this dir is read by the python RIS implementation processes.

sys/ – the drivers themselves

i386/ – the cab files and other files found on the i386 directory on the media

amd64/ – on 64 bit OSes, this contains 64b versions of the i386 files.

The boot directory is populated as follows. Modifications need to be made to the actual windows binaries using your binary editor of choice. There are several strings, such as “winnt”, prevalent throughout all of the binaries and they each need to be replaced with a new string. This is done to create uniqueness across all of the windows install variants all of which request the same files such as winnt.sif, ntdetect.com, and whatnot. Using your binary or hex editor of choice, and substitute the following strings:

  • startrom.n12 – NTDLR to w50aa
    • rename this file to w50aa.0
  • setupldr.exe – winnt.sif to w50aa.sif; ntdetect to ntdw50aa;
    • rename this file to w50aa
  • ntdetect.com – no string replacement
    • rename this file to ntw50aa.com

Alternatively, the following script snippet can be adopted to use. In the example below let ${Lwhich}=”w50aa”. The full script can be found at http://www.karlmajer.com/files/addnewos/addnewos.sh. Note, if using the script, the script assumes you’ve created the directory w50aa/i386 and/or w50aa/amd64 depending on the bitness of the OS and copied the files from the install media to those locations.

echo “Preparing boot directory.”
echo “…cabextracting files…”
cabextract -d boot/ i386/startrom.n1_
cabextract -d boot/ i386/setupldr.ex_

echo “…copying files…”
cp i386/ntdetect.com boot/

echo “…editing binaries…”
echo “…..startrom.n12…”

cat > /tmp/${Lwhich}.startrom.$$ << EOF
:%s/NTLDR/${Lwhich}/g
:wq!
EOF
vim -b -s /tmp/${Lwhich}.startrom.$$ boot/startrom.n12

echo “…..setupldr.exe…”

cat > /tmp/${Lwhich}.setupldr.$$ << EOF
:%s/winnt.sif/${Lwhich}.sif/g
:%s/ntdetect/ntd${Lwhich}/g
:wq!
EOF
vim -b -s /tmp/$Lwhich.setupldr.$$ boot/setupldr.exe

echo “…renaming binaries…”
mv boot/ntdetect.com boot/ntd${Lwhich}.com
mv boot/setupldr.exe boot/${Lwhich}
mv boot/startrom.n12 boot/${Lwhich}.0

You’ll note the vim is being used in binary mode (-b) in order to do the edits. The stubfiles simply create regex expressions for vim that are used to handle the search and replace. The script also handles the renames for you as well.

When it is all said and done, you will have the following files in the boot directory: w50aa, w50aa.0, and ntdw50aa.com. If you’re using the full version of the script then a w50aa.sif configuration file will have been created also. Those files map to the old ntldr, ntdetect, and then the setup specific files, setupldr.exe and the winnt.sif file.

To populate the i386 directory all that is required is to copy the i386 directory off the media directly into the tree.

For the inf and sys directories, the following needs to be done. Note that ${BIT} denotes 32 or 64 bit and pulls files from the appropriate directories accordingly. Again, this is included in the script linked above.

echo “Preparing inf and sys directories.”

if [ ${BIT} ];
then
echo “…extracting inf files…”
cabextract -d inf amd64/[Nn][Ee][Tt]*.[Ii][Nn]_
echo “…extracting sys files…”
cabextract -d sys -F *.sys amd64/driver.cab
else
echo “…extracting inf files…”
cabextract -d inf i386/[Nn][Ee][Tt]*.[Ii][Nn]_
echo “…extracting sys files…”
cabextract -d sys -F *.sys i386/driver.cab
fi

echo “Complete.”

That takes care of the directories. The only remaining things to do are to update the tftpd.map file and to create a few symlinks to fix bizarre windows naming conventions as well as update the windirs.conf which is the binl parser configuration file and update it to include this new OS we’ve added. Both of these are covered in detail in the script.

That concludes the preparation of the windows image. The next section will discuss setting up the low level boot and PXE environment.

>>> Karl

No responses yet

Jan 16 2008

Multi-OS Installation: Configuring the Windows Image – Part 1

It takes a bit of work to prepare the contents of a windows CD image for use with the installation system. There is nothing terribly complicated about the process but it is a somewhat tedious, and after the 20th or so image that is being prepared, you may find yourself wishing for a script or two to simplify things. This is not to worry, I will provide those as well.

First a bit of background on the windows boot process. As a windows machine starts the boot process, the following things happen approximately in this order (1):

  1. The MBR is queried for the boot sector, and Ntldr is read.
  2. Ntldr is loaded into memory. Its reads the Boot.ini file to present the menu and loads the kernel.
    1. Ntldr will eventually load Ntoskernl.exe, Bootvid.dll Hal.dll and the boot-start device drivers.
  3. Ntdetect.com then runs and performs a basic hardware detection for Ntldr.
  4. Ntbootdd.sys is loaded for I/O.
  5. Ntoskrnl.exe is initialized and starts the system-start device drivers then kicks off smss.exe
  6. Hall.dll is loaded and is used to speak to the hardware in the machine.
  7. Smss starts the windows subsystem.
  8. Winlogon is started.
  9. SCM (service control manager) is started for windows services/drivers.

The boot process across the network is somewhat similar:

  1. The pxeclient on the network interface in computer drops a boot request onto the wire.
  2. The dhcp server catches this request and gives the pxeclient an IP address, the IP address of the next server in the process, and the name of the file to fetch. .
    1. pxelinux was used for the windows installs.
  3. The pxeclient then fetches pxlinux via tftp from the bootserver and presents the menu to the user and waits for entry.

Up until this point the pxe boot procedure is the same regardless of what OS is being loaded.

  1. The user selects the desired windows installation and pxelinux tftps back to the server and asks for the appropriate file, typically startrom.n12, the network bootloader for the MS boot process.
  2. startrom.n12 then calls for setupldr.exe
  3. setupldr.exe, actually named ntldr on the filesystem, is the pre-installation setup loader for windows.
  4. as before ntldr calls ntdetect.com for hardware detection,
  5. similarly, ntdetect.com handles hardware detection for the ntldr process as for the disk based boot
  6. finally the file winnt.sif is loaded which contains the instructions for the setup/RIS based installation.

Now, in order to make this all work a bit of filename manipulation magic needs to be undertaken. This is accomplished in the tftpd.map file which is loaded by the tftp server and additionally by making a few changes to both the names of the binaries and to the binaries themselves.

The naming convention chosen at the site was based on the fact that NTLDR is five characters. A method to encode OS names/types into the five characters was devised such that any OS/SP level could be encoded. The first letter was either W for 32 bit or X for 64 bit. The next two characters were the Microsoft OS version number, W50 for Windows 2000 32bit, X51 for Windows XP Pro 64 Bit. Finally the last two characters were used to denote patch level and any other desired information. For example, at the client site, X51AA was an unpatched XP Pro 64 Bit. While X51BA was SP2.

The path used on the filesystem to contain the filesystem images was /export/install/images. The tftp root is /export/install. The mapfile contained:

# windows to unix pathing
rgi \\ /

# anything asking for /IMAGES is broken and likely a Microsoft client.
rge ^/IMAGES/ /images/

# rehome 32 and 64 2k and 2k3 to /images
rgi ^/X5.* /images\0
rgi ^/W5.* /images\0
# Windows 2000 32 bit – W50AA

rgi ^/boot/pxelinux.0ntdw50aa.com /images/W50AA/boot/ntdw50aa.com
rgi ^boot/pxelinux.0ntdw50aa.com /images/W50AA/boot/ntdw50aa.com
rgi ^/boot/pxelinux.0w50aa.sif /images/W50AA/boot/w50aa.sif
rgi ^boot/pxelinux.0w50aa.sif /images/W50AA/boot/w50aa.sif
rgi ^w50aa /images/W50AA/boot/w50aa
rgi ^/images/W50AA/i386/W50AA/sys/(.*) /images/W50AA/sys/\1

# Windows XP Professional 64bit – X51AA
rgi ^x51aa /images/X51AA/boot/x51aa
rgi ^ntdx51aa.com /images/X51AA/boot/\0
rgi ^x51aa.sif /images/X51AA/boot/\0
rgi X51AA/i386 X51AA/amd64
rgi ^/images/X51AA/amd64/X51AA/sys/(.*) /images/X51AA/sys/\1
rgi ^/images/X51AA/i386/X51AA/sys/(.*) /images/X51AA/sys/\1

First off we need to rewrite dos paths to unix paths. Next we need to send anything asking for just /[WX]5 to /images. That allows the client to find the files its going to request next. The next section addresses some bugs in windows 2000 in which it tacks on the file its looking for onto the file it loaded previously, ie the pxelinux bootloader. Thankfully XP lacks this bug. You’ll notice that the filenames are not those mentioned in the process flow earlier, but are instead files based on the new naming convention. Any additional OSes based on 2000 need to simply copy the 2000 stanza and adjust the w50aa to the new 5 digit code. The same holds true for XP. These mappings allow the pxeclient to find the contents of the appropriate boot directory.

Configuring the directories in the W51AA tree will be covered in the next post.

>>> Karl

(1. This disk based bootup process was adapted from “Table 5-1, Microsoft Windows Internals, Fourth Edition, p252″. Any typos are mine. I’d recommend the original version of this from the text if possible. Its one of the few windows reference books on my shelf.)

No responses yet

Jan 16 2008

Multi-OS Installation: Configuring the Windows Environment.

Ah, the wonderful world of MS Windows. An environment ripe with complexities and peculiarities unique to the GUI based world loved and scorned by many. Traditionally, the windows installation procedure requires a windows RIS server to handle the duties of the installation server. The production Multi-OS install server was ultimately a Redhat EL 5 64bit host, however all of my development work and the prototype were built on an intel Solaris 10 64 bit installation.

The system built for the client, however, made use of both a single box running tftp, samba, and the python RIS implementation from http://oss.netfarm.it/guides/pxe.php. The basic setup is as follows:

TFTP – tftp-hpa 0.42 – With remap and with tcpwrappers was chosen as the tftp server to be used. The using of tcpwrappers is generally a good practice, but the remap function was the desired functionality in this version of tftpd. RHEL 5 ships with this binary as an rpm. The map file will be explained in further detail in when the image preparation is discussed.

SAMBA – samba 3.023c-2 – Was selected as the version of samba to run. Again, this was available as an rpm on RHEL 5 and made the selection easy. The following lines were added to the smb.conf configuration file to support the RIS installation environment:

encrypt passwords = yes
null passwords = yes
socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192
idmap uid = 16777216-33554431
idmap gid = 16777216-33554431
template shell = /bin/false
winbind use default domain = no
guest account = nobody
map to guest = Bad User

The last line allows any user that fails authentication to map to the guest account. If the samba server is setup on a different domain than the rest of the organization, as it was in the case on this network, the desktop computers will have access to the CIFS shares to pull cabs, or other files, from the CD images available on the shares. Note: While testing on unix using smbclient, the share name is \\\\HOST\\SERVICE. If you happen to add a trailing \\ on the end, the service name wont match and the connection will fail with a “tree connect failed: NT_STATUS_BAD_NETWORK_NAME.”

RIS – The UDA v 1.4 provided the foundation binlsrv.py and infparser.py files that were used to initialize the 32 bit OSes. As written, the core binl code needed to be refactored and extended for the intelligent inclusion of additional operating systems, both 32 and 64 bit. The biggest change was made to the infparser and allows it to read the list of operating systems to be parse from a text file. A link to my updated versions of the files can be found here: binlsrv.py, infparser.py, and windirs.conf.sample.

Once the requisite software has been installed, the image will need to be prepared. This will be covered in the next section entitled “Multi-OS Installation: Configuring the Windows Image.”

4 responses so far