pxelinux and Windows

Installing RedHat / Fedora / CentOS over the network using pxelinux is pretty straightforward. But installing Windows with pxelinux is a bit harder (what a suprise…)






Setup

My setup contains the following systems:

  • Windows 7 (x64)
  • CentOS 6 (x64)
  • 1 VM running on VMware Workstation, able to boot from the same network as CentOS 6 server


Preparing an Windows PE image

First you need a valid Windows P(re) E(xecute) image, this requires you to download the Windows Automated Installation Kit (AIK). Be warned though, it’s a huge download…
Once you have to download you can install the AIK, run StartCD.exe from the cd and click on Windows AIK Setup
After installation you can start the Deployment Tools Command Prompt, it should be in your start menu under Microsoft Windows AIK

Please note that you need to run this under Administrator Privileges (right click –> run as administrator)

Run the following commands to create a WinPE image:

 
> set WAIKPath=%ProgramFiles%\Windows AIK
> set PEPath=C:\WinPE
> set BootName=windows7-x64
> set TFTPPath=C:\tftp\%BootName%
> set BCDStore=%TFTPPath%\BCD
> set arch=amd64

> copype %arch% %PEPath%
> imagex /mountrw winpe.wim 1 mount
> mkdir %TFTPPath%
> copy mount\Windows\Boot\PXE\* %TFTPPath%
> copy "%WAIKPath%\Tools\PETools\%ARCH%\boot\boot.sdi" %TFTPPath%
> copy winpe.wim %TFTPPath%
> mkdir %TFTPPath%\Fonts
> copy mount\Windows\Boot\Fonts\wgl4_boot.ttf %TFTPPath%\Fonts
> cd mount\Windows\System32
> bcdedit -createstore %BCDStore%
> bcdedit -store %BCDStore% -create {ramdiskoptions} /d "Ramdisk options"
> bcdedit -store %BCDStore% -set {ramdiskoptions} ramdisksdidevice Boot %BootName%
> bcdedit -store %BCDStore% -set {ramdiskoptions} ramdisksdipath \%BootName%\boot.sdi
> bcdedit /store %BCDStore% /create /d "Windows 7 Install Image" /application osloader
The entry {c9e1cba0-d192-11e0-b6ab-001d60aeed1b} was successfully created.
> set GUID={c9e1cba0-d192-11e0-b6ab-001d60aeed1b}
> bcdedit -store %BCDStore% -set %GUID% systemroot \Windows
> bcdedit -store %BCDStore% -set %GUID% detecthal Yes
> bcdedit -store %BCDStore% -set %GUID% winpe Yes
> bcdedit -store %BCDStore% -set %GUID% osdevice ramdisk=[boot]\%BootName%\boot.wim,{ramdiskoptions}
> bcdedit -store %BCDStore% -set %GUID% device ramdisk=[boot]\%BootName%\boot.wim,{ramdiskoptions}
> bcdedit -store %BCDStore% -create {bootmgr} /d "Windows 7 Boot Manager"
> bcdedit -store %BCDStore% -set {bootmgr} timeout 30
> bcdedit -store %BCDStore% -set {bootmgr} displayorder %GUID%
> bcdedit -store %BCDStore%
> cd %PEPath%
> imagex /unmount mount
 

The GUID you get on line 23 is unique, so don’t blindly copy/paste line 24.

If nothing went wrong you have a Windows 7 PXE image configured in %TFTPPath% (in my case c:\TFTP\windows7-x64).
Copy this directory to your linux server, I placed it in /var/lib/tftpboot/images/

Install required software

You will need to install the following software:

 
[root@stargate ~]# yum -y install dhcp tftp-server xinetd samba syslinux
 


Configure TFTP

Create a tftp-remap file

 
[root@stargate ~]# cat > /var/lib/tftpboot/tftp.remap<<EOF
rg \\                /
ir ^Boot/            images/windows7-x64/
ir ^/Boot/           images/windows7-x64/
ir ^windows7-x64/    images/windows7-x64/
ir ^/windows7-x64/   images/windows7-x64/
re ^bootmgr\.exe     images/windows7-x64/bootmgr.exe
EOF
 

NOTE: A very big disadvantage is that Windows always looks in /Boot directory on the TFTP server. Which implies using different processors (32 and 64 bit) is impossible.

Place the Windows PXE image directory in the right directory, and reset the permissions, and create some symlinks

 
[root@stargate ~]# mv ~richard/windows7-x64 /var/lib/tftpboot/images/
[root@stargate ~]# chown -R root: /var/lib/tftpboot/images/windows7-x64/
[root@stargate ~]# find /var/lib/tftpboot/images/windows7-x64 -type d -exec chmod 755 "{}" \;
[root@stargate ~]# find /var/lib/tftpboot/images/windows7-x64 -type f -exec chmod 644 "{}" \;
[root@stargate ~]# ln -s pxeboot.n12 /var/lib/tftpboot/images/windows7-x64/startrom.0
[root@stargate ~]# ln -s winpe.wim /var/lib/tftpboot/images/windows7-x64/boot.wim
 

Edit /etc/xinet.d/tftp and set:

 
service tftp
{
        socket_type             = dgram
        protocol                = udp
        wait                    = yes
        user                    = root
        server                  = /usr/sbin/in.tftpd
        server_args             = -s /var/lib/tftpboot -m /var/lib/tftpboot/tftp.remap -vvv
        disable                 = no
        per_source              = 11
        cps                     = 100 2
        flags                   = IPv4
}
 

Make sure you set the server_args and disable on no.

Copy the required syslinux files to the tftp root directory

 
rpm -ql syslinux | grep -e '/pxelinux.0' -e '/menu.c32' | while read FILE; do
  cp -a "$FILE" /var/lib/tftpboot/;
done
 

And create the default PXE configuration

 
[root@stargate ~]# mkdir -p /var/lib/tftpboot/pxelinux.cfg
[root@stargate ~]# cat > /var/lib/tftpboot/pxelinux.cfg/default<<EOF
DEFAULT menu
PROMPT 0
MENU TITLE pxeBoot | http://www.falsyana.com
TIMEOUT 200
TOTALTIMEOUT 600
ONTIMEOUT local

LABEL local
        MENU LABEL (local)
        MENU DEFAULT
        LOCALBOOT 0

LABEL Windows 7
        MENU LABEL Windows 7 PE (x64)
        KERNEL windows7-x64/startrom.0

MENU end
EOF
 


Configure DHCP

Edit /etc/dhcp/dhcpd.conf, change the ip’s to your own range:

 
ddns-update-style interim;
ignore client-updates;
authoritative;

subnet 172.24.4.0 netmask 255.255.255.0 {
    next-server          172.24.4.254;
    filename             "pxelinux.0";

    range dynamic-bootp  172.24.4.10 172.24.4.20;
    default-lease-time   28800;
    max-lease-time       86400;
}
 


Configure SAMBA

The installation files of windows must be presented to the client over Samba (/CIFS). Now since my Linux server doesn’t has a cd/dvd drive I made an iso and uploaded it to my server ;-)

Mount the ISO and copy the files to an appreciate folder

 
[root@stargate ~]# mount -o loop /data/samba/applications/Microsoft\ windows\ Server\ 2008\ R2\ Enterprise\ -\ SP1\ Integrated.iso /mnt/
[root@stargate ~]# mkdir -p /media/os-install-tree/Microsoft-Windows-Server-2008-R2-Enterprise-x64
[root@stargate ~]# rsync -ar --progress /mnt/* /media/os-install-tree/Microsoft-Windows-Server-2008-R2-Enterprise-x64/
[root@stargate ~]# umount /mnt
 

And finally configure samba, add the following section to /etc/samba/smb.conf:

 
[PXE$]
        comment = "Installation trees"
        path = /media/os-install-tree/
        guest ok = yes
        writable = no
 


Start it up

Now start all our services and make them start after a reboot

 
for SERVICE in dhcpd smb xinetd; do
  chkconfig $SERVICE on
  service $SERVICE restart
done
 

And start your VM to boot from the network, you will get the following menu:

Start the Windows 7 PE, it will take some time to start (give it a minute or 3).
And you will end up with a dosbox, yes that’s it…

Here you can mount the installation tree and start the installer:

 
> net use z: \\172.24.4.254\pxe$
> z:
> cd Microsoft-Windows-Server-2008-R2-Enterprise-x64
> setup.exe
 



Custom scripts

There is the ability to run some automatic scripts (for example mount the samba share). There is a file called \windows\system32\startnet.cmd in the winpe.wim file. You can edit this as you please. For example to automatic mount my pxe$ share I would do the following:
* Start the Deployment Tools Command Prompt (as administrator)

 
> cd \WinPE
> imagex /mountrw winpe.wim 1 mount
 

Now you can edit the file WinPE\mount\windows\system32\startnet.cmd that it looks like

 
wpeinit
@net use z: \\172.24.4.254\pxe$
@echo You can find the installation tree's on Z:\
 

After you are done with editing the file you can go back to the Deployment Tools Command Prompt and type

 
> imagex /unmount /commit mount
 

And copy the winpe.wim to the Linux server /var/lib/tftpboot/images/windows7-x64/

Windows XP

If you are trying to install Windows XP you will notice that when you run setup, the install Windows XP is grayed out…
To fix this you need to format the C:\ drive manually. With diskpart you can create the partition, and then you need to run winnt32.exe with some parameters.

 
diskpart
  select disk 0
  clean
  create partition primary size=1024
  select partition 1
  active
  format
  exit
z:
cd microsoft-windows-xp-x64
i386\winnt32.exe /syspart:c:
 

NOTE:It’s slow…. very slow

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>