Install Windows XP/2003 from Linux
What do you do if you don’t have a CD-ROM drive in your laptop/desktop, and booting from USB is also not an option available at hand. Under the circumstances, installing Linux from an NFS-based install server is something we know like the back of our hand. But what if we need to install Windows on the laptop? In fact, what if we can configure a Linux-based remote installation server to install Windows?
Today, we’ll discuss how to configure a remote Windows installation server powered by Linux.
Our setup will be based on a program called RIS for Linux.
My install server is CentOS 5.4 (you can, of course, use any other Linux distribution you’re comfortable using). Make sure you have the following server services installed:
Setting Up the Server
Create a user (if one already doesn’t exist) on your system and login to that account. Now create the following directories, as follows:
mkdir -p ~/tftproot/cdrom mkdir -p ~/tftproot/drivers
Change the tftp location in the
server = /usr/sbin/in.tftpd server_args = -s /home/ajeet/tftproot -m /home/ajeet/tftpdremap -vvvv
Copy the i386 directory from your Windows CD-ROM to
~/tftproot/cdrom, as follows:
cd ~/tftproot cabextract ~/tftproot/cdrom/i386/startrom.n1_ cp ~/tftproot/cdrom/i386/setupldr.bin ntldr cp ~/tftproot/cdrom/i386/ntdetct.com .
Now, copy the
ris-linux utility in to your home directory and extract the tar. Run the following command now:
cd ~ ./fixloader.py tftproot/ntldr cabextract ~/tftproot/cdrom/i386/*.in_ -d tftproot/drivers cabextract ~/tftproot/cdrom/i386/driver.cab -d tftproot/drivers
Finally, build your drivers as follows:
Now, we all know Windows defines directory path using a back slash (\) instead of the forward slash (/) we’re used to on Linux. To take care of this issue, we have to create a new file and define instructions so that Windows can decipher the file/directory paths supplied by the Linux-based install server — in short, trasnlate / (forward slash) to \ (back slash). Let’s create a file called
/etc/tftpreadmap and append the following lines in it:
r ^\\cdrom\\i386\\pcntpci5.sys pcntpci5.sys r ^\\\\i386 i386 rg \\ / r KDCOM.DL_ kdcom.dl_ r KDCOM.DLL kdcom.dll r BOOTVID.dl_ bootvid.dl_ r BOOTVID.dll bootvid.dll r SETUPREG.HIV setupreg.hiv r SPDDLANG.SY_ spddlang.sy_ r SPDDLANG.SYS spddlang.sys r WMILIB.SY_ wmilib.sy_ r WMILIB.SYS wmilib.sys r 1394BUS.SY_ 1394bus.sy_ r 1394BUS.SYS 1394bus.sys r PCIIDEX.SY_ pciidex.sy_ r PCIIDEX.SYS pciidex.sys r USBPORT.SY_ usbport.sy_ r USBPORT.SYS usbport.sys r USBD.SY_ usbd.sy_ r USBD.SYS usbd.sys r HIDCLASS.SY_ hidclass.sy_ r HIDCLASS.SYS hidclass.sys r HIDPARSE.SY_ hidparse.sy_ r HIDPARSE.SYS hidparse.sys r SCSIPORT.SY_ scsiport.sy_ r SCSIPORT.SYS scsiport.sys r CLASSPNP.SY_ classpnp.sy_ r CLASSPNP.SYS classpnp.sys r TDI.SY_ tdi.sy_ r TDI.SYS tdi.sys r OPRGHDLR.SY_ oprghdlr.sy_ r OPRGHDLR.SYS oprghdlr.sys r VIDEOPRT.SY_ videoprt.sy_ r VIDEOPRT.SYS videoprt.sys r HALAACPI.DL_ halaacpi.dl_ r HALAACPI.DLL halaacpi.dll r iaStor iastor r Fasttx2k fasttx2k r S150sx8 s150sx8 r QL2300 ql2300 r Si3112 si3112 r SiSRaid sisraid r RTL8139.SY_ rtl8139.sy_ RTL8139.SYS rtl8139.sys
Let’s now set the correct location in the following file:
[data] floppyless = "1" msdosinitiated = "1" ; Needed for second stage OriSrc = "\\Attila\RemInst\windows\i386" OriTyp = "4" LocalSourceOnCD = 1 DisableAdminAccountOnDomainJoin = 1 [SetupData] OsLoadOptions = "/fastdetect" ; Needed for first stage SetupSourceDevice = "\Device\LanmanRedirector\Attila\RemInst\windows" [RemoteInstall] ; Avoid automatic format/repartition Repartition = No UseWholeDisk = No [UserData] ComputerName = * ProductID=XXXXX-XXXXX-XXXXX-XXXXX-XXXXX
Note: Replace the XXXX in the last line of the above file with the correct product/license key of your Windows.
Now set up
/etc/dhcpd.conf with the appropriate information of your network range and other assorted details. Following is what the file looks like on my system:
range dynamic-bootp 192.168.0.128 192.168.0.56; default-lease-time 21600; max-lease-time 43200; next-server 192.168.0.16; filename "startrom_n12";
Next up, we’ll need to configure Samba. Here’s what my
smb.conf file looks like:
[global] panic action = /usr/share/samba/panic-action %d guest account = root null passwords = true security = share workgroup = workgroup server string = RIS Server syslog only = no syslog = 0; socket options = IPTOS_LOWDELAY TCP_NODELAY SO_SNDBUF=4096 SO_RCVBUF=4096 encrypt passwords = true wins support = no name resolve order = lmhosts host wins bcast dns proxy = no unix password sync = false max log size = 1000 unix charset = iso-8859-15 display charset = iso-8859-15 dos charset = 850 [REMINST] browseable = yes read only = no path = /home/ajeet/tftproot guest ok = yes
The final step is to configure the start scripts for all drivers — in other words, the driver information that are requested by the client installation environment to the server BINL daemon. Create a file named
~/binlsrv.py and append the following lines in it:
set base path BASEPATH = '/home/ajeet/tftproot/winxp/i386/'
That’s it. Now, you can simply execute the following command to boot the remote machine using PXE:
In case, if any errors prop up regarding your driver, no need to panic. Download all drivers from your vendor site and using the
cabextract utility copy them into
Run the above command again and things should get going now.
Pretty cool, eh? Open Source is so inclusive that it even provides tools to set up remote Windows installation servers based on Linux. Now no need to go sit next to each client machine and install Windows from the media disc — one install server will take care of your head aches.
Here’s a common error screen you might encounter:
In case you encounter the above on your client machine while installation, check your
tftp-readmap file again to figure out the issue in the setup.
Another common error screen is the following:
Again, nothing worth panicking at all — it’s just a Samba problem. Check
[global] options defined in your
Finally, remember to not blindly copy paste the instructions from here to your system. In some of the config files that I’ve reproduced above, the directory/file paths start with
/home/ajeet/. That’s because ajeet is my user name. So, make sure you change these
/home/ajeet/ definitions with the appropriate paths on your setup system.