Archive for January, 2008

Jan 21 2008

Multi-OS Installation: Windows Final Steps

This is my second attempt at writing this post. I was using ecto this morning for the last time while writing the first iteration of this post and when switching between html and text mode the app decided to eat the post for me. Hopefully this iteration will be as good as the first, if not better…

So, there are a few things left to do before we can attempt a network boot. Primarily we need to add/create the winnt.sif configuration file, update the binl daemon files and restart the daemon, and then we need to test the components to make sure that everything is in order.

An absolute minimal winnt.sif created by the addnewos.sh script looks like the following:

[data]
floppyless = "1"
msdosinitiated = "1"
; Needed for second stage
Orisrc="\\\\172.16.32.16\REMINST\\W50AA\i386"
OriTyp = "4"
LocalSourceOnCD = 1
;DisableAdminAccountOnDomainJoin = 1
[SetupData]
OsLoadOptions = "/fastdetect"
; Needed for first stage
SetupSourceDevice = "\Device\LanmanRedirector\172.16.32.16\REMINST\\W50AA"
[UserData]
ComputerName = *
FullName = *
OrgName = *
ProductID = *

Briefly, the [data] section specifies where the media will be coming from and what type it is. The [SetupData] stanza contains any arguments to be passed to the kernel, as well as establishing the source device from which setup is to pull the additional datafiles. The listed path corresponds to the samba share that was setup earlier.

Finally, the [UserData] section allows for the customization of the computer name, the user name, and the company name, as well as provide a slot to prefill the appropriate license key obtained from Microsoft.

This sif file will allow setup to execute in a fully interrogative mode, asking the user performing the install the same series of questions as if they’d used the CD media for the installation. There are quite a few options available for the sif file allowing for the full unattended installation of windows. If there is an interest I can expand on it in a future piece.

Once the w50aa.sif file is in place, we can go refresh the binlsrv.py database. Assuming the copies of binlsrv.py, infparser.py, and windirs.conf.sample were obtained from this site, this is accomplished by doing the following:

  • edit windirs.conf and add the new directory name, i.e. W50AA
  • run infparser.py
  • run binlsrv.py

With the binlsrv.py script running, we can begin to do the testing on the system. Of course you could at this point simply reboot the box you wish to install, cross your fingers, and hit F12 to netboot while hoping for the best. Those of you willing to use some methodology in their testing, please read on. Please note: I’m assuming the path to your install tree is /export/install/ and you have the windows image in images/W50AA. You’ll need to adjust it for your environment otherwise.

First we need to make sure dhcpd is running:

ps -ef | grep dhcpd

Next we ensure binlsrv.py is running;

ps -ef | grep binl

Now we make sure that the repository is in proper order:

ls -al /export/install/pxelinux	   # check for pxelinux
ls -al /export/install/default     # check for the default menu file for pxelinux
ls -ald /export/install/images/W50AA/i386 # make sure the i386 dir is there
ls -ald /export/install/images/W50AA/w50aa* # we should get 3 files back, w50aa, w50aa.0, w50aa.sif.

Now we make sure that tftp is working as expected (remember that tftp was chrooted to /export/install so everything will be relative to that path):

tftp localhost
cd images/W50AA/boot
get w50aa.sif

Now we ensure that the rewriting rules for the tfpd map files worked properly

grep W50AA /var/log/messages  # on linux
grep W50AA /var/adm/messages  # on solaris

You should have seen several log lines spit out as a match to the grep statement. If not, there is the possibility that the mapping isn’t working. Try a tail -f on the logfile and run a few tftp fetches by hand looking for the matches.

At this point the only thing left to do is the actual boot of the computer. So, reboot the test machine, netboot it, and if all goes well you will be greeted by the pxelinux menu. From there pick the entry you created for the windows installation and you will soon be greeted by the windows setup program.

Hopefully there is enough in here to allow you to troubleshoot any issues which you may run into. If this is not the case, please post in the comments and I’ll do what I can to assist you.

>>> Karl

No responses yet

Jan 19 2008

Multi-OS Installation: Configuring the PXE Loader Environment

This article is one in a series detailing the implementation of a Multi-OS boot environment. While the article should stand on its own, it may be generally helpful to read the other articles in the series for the highest level of understanding.

The configuration of the PXE environment requires several components:

  • dhcpd server
  • tftpd server
  • PXE bootloader

Each of these items has customized configuration files which will be described below.

At the lowest level there is a dhcpd server listening for initial boot requests. ISC’s dhcpd server, specifically version 3.0.6 which was the current version at the time. On the production RHEL machine, version 3.0.5 from the RPM was used.

The full intricacies of configuring the dhcpd file can be found in the manpage, however at a minimum one needs to specify the following pxelinux entries and create a single subnet stanza for basic functionality.

# pxelinux settings
option space pxelinux;
option pxelinux.magic code 208 = string;
option pxelinux.configfile code 209 = text;
option pxelinux.pathprefix code 210 = text;
option pxelinux.reboottime code 211 = unsigned integer 32;

#and

# Servers subnet
subnet 172.16.32.0 netmask 255.255.254.0 {
authoritative;
option routers 172.16.32.1;
option subnet-mask 255.255.254.0;
option broadcast-address 172.16.33.255;
option domain-name “dhcp.karlmajer.com karlmajer.com”;
range dynamic-bootp 172.16.33.201 172.16.33.251;

ddns-domainname “dhcp.karlmajer.com”;
ddns-rev-domainname “dhcp.33.30.172.in-addr.arpa.”;

next-server 172.16.32.16;

filename “boot/pxelinux.0″;
site-option-space “pxelinux”;
option pxelinux.magic f1:00:74:7e;
option pxelinux.configfile “pxelinux.cfg”;
option pxelinux.pathprefix “/tftpboot/pxelinux/files/”;
option pxelinux.reboottime 30;
}

Several assumptions are made by that configuration snippet that will need updating:

  1. *There is no other dhcpd server on the network*
  2. The tftpd server is at 172.16.32.16
  3. The default router is at 172.16.32.1
  4. You’ve placed your pxelinux and configuration files in $TFTPROOT/boot directory
  5. Your network spans 2 class Cs, i.e. the 255.255.254 (/23) netmask and 33.255 broadcast.

After making these changes in the dhcpd.conf file, start up the daemon using the method of your choice, i.e., service dhcpd start, svcadm enable dhcpd, or even simply ‘dhcpd’ from the command line.

At this point there should be a functioning dhcpd server on the network. The next thing to configure is the tftpd server. Tftp-hpa version 0.42 was chosen as the tftp server of choice as it supported the remapping of file paths in requests, and offered tcp wrappers as an added bonus. Edit the tftpd.map file, often sought by tftpd at /etc/tftpd.map, and add the following lines to it:

rgi ^pxelinux.0 /boot/pxelinux.0
rgi ^pxelinux.cfg/ /boot/
rgi ^boot/pxelinux.cfg/ /boot/
rgi ^boot// /

This sets up the location of the boot files relative to the tftpd root which is specified on startup. In the environment that was built, all provisioning related items were placed in /export/install and the tftpd daemon was chrooted to this path. Therefore the pxelinux related files were in /export/install/boot, the menu files were in /export/install/hostmenu.

Now the tftpd server can be run from either inetd or as a standalone. Given the low usage of the install system, it was decided that tftpd would run from xinetd on RHEL ignoring the startup/shutdown costs of the daemon which may be noticeable were the install frequency several installs per hour rather than week.

Configuration of the inetd process will differ depending on the flavor of unix employed. On RHEL one need simply add a service definition to the xinetd.d directory and the xinetd daemon will pick it up on the next invocation. A sample RHEL stanza looks as follows:

# default: off
# description: The tftp server serves files using the trivial file transfer \
# protocol. The tftp protocol is often used to boot diskless \
# workstations, download configuration files to network-aware printers, \
# and to start the installation process for some operating systems. service tftp
{
socket_type = dgram
protocol = udp
wait = yes
user = root
server = /usr/sbin/in.tftpd
server_args = -m /etc/tftpd.map -v -v -v -s /export/install -t 10
disable = no
per_source = 11
cps = 100 2
flags = IPv4
}

Note the explicit paths to the tftpd.map as well as the chroot to /export/install.

At this point we have a daemon to respond to our PXE requests, and we have a daemon to serve the content using the tftp protocol for the PXE requests. Now we need to supply the file to be served.

PXELinux from http://syslinux.zytor.com/pxe.php was used as the bootloader. The files were unbundled and placed into /export/install/boot. A menu file was created for pxelinux, the contents of which look like:

#Note, this menu starts the local disk, a memtest utility, and a Windows 2000 RIS #Installation.
default local
prompt 1
timeout 0
display /boot/install.msg
F1 /boot/install.msg

label local
localboot 0

label w50aa
kernel /images/W50AA/boot/w50aa.0

label memtest
kernel /boot/memtest
append -

For safety the default configuration chosen is to always favor the internal drives and only attempt to boot from the w50aa stanza on request. Now copy the menu containing the described data into the /export/install/boot/ (adjusted appropriately for your filesystem layout) and either name the file default, or name the file something else and symlink it to default.

At this point you should have the basic workings of a PXE loader environment. To test it first make sure that dhcpd is running:

ps -ef | grep dhcpd

Next use tftp to connect to localhost and request the file pxelinux:

tftp localhost
get pxelinux

Finally, reboot a host with a PXEboot capable network adapter and hit F12 to netboot.

Please let me know if you have any questions or comments.

>>> Karl

2 responses so far

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

« Prev - Next »