Installing Windows using PXELINUX
This guide will assume you already have a functioning PXELINUX setup and want to add a Windows boot option to it.
Contents |
Requirements
- Windows host with the Windows Automated Installation Kit for Windows 7 installed. This can be a workstation.
- PXELINUX Linux host already set up.
- DHCP Server setup to direct your PXE Boot clients to your PXELINUX Linux host.
- A NETBIOS share on your fileserver for your PXE clients to access. Preferably being password-less and read only. This will be referred to as fileserver or \\fileserver\pe in this guide.
- Windows Install DVD
Windows Installation Files
- Create a directory in the \\fileserver\pe share called win7x64
- Copy the files out of the sources directory on your Windows 7 x64 DVD to the new directory.
Install.bat
- Copy your c:\windows\system32\choice.exe to your \\fileserver\pe share.
- Copy and paste the following code into a file called install.bat in the \\fileserver\pe share.
- Set the FILESERVER to your fileserver hostname or preferably its IP address.
- Set the SHARE to the name of the share.
@echo off set FILESERVER=fileserver set SHARE=pe @echo off rem ############################################################################ rem This is the subroutine to draw the menu rem ############################################################################ :menu rem Clear the screen cls rem Draw the menu, max is 24 lines by 80 characters across echo. echo Please choose an install option echo. echo 1 - Exit the installer and return to a shell echo. echo 2 - Windows 7 x64 echo Home Basic, Home Premium, Professional, Ultimate echo. rem Prompt for a choice rem Add more options after the /c rem rem /c - possible choices rem /d - default option rem /m - message to display rem /t - seconds to wait rem rem choice /c:<options> /d <default option> /m "<message>" /t <timeout seconds> rem \\%FILESERVER%\%SHARE%\choice.exe /c:12 /d 2 /m "Install option:" /t 30 if errorlevel 3 goto menu3 if errorlevel 2 goto menu2 if errorlevel 1 goto end goto menu rem ############################################################################ rem These are subroutines to run the installer for each menu choice rem ############################################################################ :menu2 echo. cls echo Running installer for: Windows 7 x64 \\%FILESERVER%\%SHARE%\win7x64\setup.exe goto end :menu3 echo. cls echo Running installer for: Windows 2008 R2 x64 \\%FILESERVER%\%SHARE%\win2k8r2x64\setup.exe goto end :end echo. echo Run 'startnet' to run the installer again. echo. echo Have a nice day! echo.
Windows PE Image Creation
Run this as a batch file or copy and paste it into the Deployment Tools Command Prompt. Make sure you are running the Deployment Tools Command Prompt and not a regular command prompt because it sets up a few variables for you. There is a link to it on the start menu under Microsoft Windows AIK. You will need about 300MB of free space. I would recommend changing the image via this script and not manually modifying any files in the image if you mount the image by hand. That is an easy way to forget the changes you have made for when you need to rebuild the image for whatever reason.
@echo off
rem The fileserver and share
set FILESERVER=fileserver
set SHARE=pe
rem ARCH=amd64 or ARCH=x86 or ARCH=ia64
set ARCH=amd64
rem Path to your Windows AIK
set WAIKPATH="%ProgramFiles%\Windows AIK"
rem Temporary path
set PEPATH="c:\winpe_%ARCH%"
rem ##########################################################
rem Don't edit anything below here
rem ##########################################################
echo Creating the PE image
call copype.cmd %ARCH% %PEPATH% > NUL
echo Mounting the image
dism /mount-wim /wimfile:%PEPATH%\winpe.wim /index:1 /mountdir:%PEPATH%\mount > NUL
echo Adding commands to the startup script in PE
echo ping -n 1 %FILESERVER% >> %PEPATH%\mount\windows\system32\startnet.cmd
echo \\%FILESERVER%\%SHARE%\install.bat >> %PEPATH%\mount\windows\system32\startnet.cmd
echo Creating the pxeboot directory
mkdir %PEPATH%\pxeboot > NUL
mkdir %PEPATH%\pxeboot\Fonts > NUL
copy %PEPATH%\mount\windows\boot\pxe\bootmgr.exe %PEPATH%\pxeboot\ > NUL
copy %PEPATH%\mount\windows\boot\pxe\pxeboot.n12 %PEPATH%\pxeboot\pxeboot.0 > NUL
copy %PEPATH%\mount\windows\boot\fonts\wgl4_boot.ttf %PEPATH%\pxeboot\Fonts\ > NUL
copy %WAIKPATH%\Tools\PETools\%ARCH%\boot\boot.sdi %PEPATH%\pxeboot > NUL
echo Unmounting the image
Dism /unmount-Wim /MountDir:%PEPATH%\mount /Commit > NUL
copy %PEPATH%\winpe.wim %PEPATH%\pxeboot\boot.wim > NUL
echo Creating the boot file
set BCDStore=%PEPATH%\pxeboot\BCD
bcdedit -createstore %BCDStore% > NUL
bcdedit -store %BCDStore% -create {ramdiskoptions} /d "Ramdisk options" > NUL
bcdedit -store %BCDStore% -set {ramdiskoptions} ramdisksdidevice Boot > NUL
bcdedit -store %BCDStore% -set {ramdiskoptions} ramdisksdipath \Boot\boot.sdi > NUL
for /f "Tokens=3" %%i in ('bcdedit /store %BCDStore% /create /d "Windows 7 Install Image" /application osloader') do set GUID=%%i
bcdedit -store %BCDStore% -set %GUID% systemroot \Windows > NUL
bcdedit -store %BCDStore% -set %GUID% detecthal Yes > NUL
bcdedit -store %BCDStore% -set %GUID% winpe Yes > NUL
bcdedit -store %BCDStore% -set %GUID% osdevice ramdisk=[boot]\Boot\boot.wim,{ramdiskoptions} > NUL
bcdedit -store %BCDStore% -set %GUID% device ramdisk=[boot]\Boot\boot.wim,{ramdiskoptions} > NUL
bcdedit -store %BCDStore% -create {bootmgr} /d "Windows 7 Boot Manager" > NUL
bcdedit -store %BCDStore% -set {bootmgr} timeout 30 > NUL
bcdedit -store %BCDStore% -set {bootmgr} displayorder %GUID% > NUL
echo ##########################################################
echo All the files you need for your PXE server are in: %PEPATH%\pxeboot\
PXELINUX
Boot Files
Copy the files from the pxeboot directory on your Windows host that was created during the Windows PE Image creation process with the script to your TFTP directory on your Linux host.
Note: the empty file is an empty file I created. This is to help speed up the boot process. I noticed the PXE client would poll for a few files while loading the PE environment, wasting valuable install time. This helped save a few seconds by returning an empty file.
Note: Your tftproot directory may be different then mine. It might be tftpboot or something.
Note: Case matters. Fonts is Fonts, not fonts. You don't really need the Fonts directory, but Windows PE checks for it, so might as well put it there.
/tftproot/winpe -rw-r--r-- 1 root root 12K Feb 12 14:51 BCD drwxr-xr-x 2 root root 4.0K Feb 12 14:56 Fonts -rw-r--r-- 1 root root 3.1M Feb 12 15:02 boot.sdi -rw-r--r-- 1 root root 130M Feb 12 14:51 boot.wim -rw-r--r-- 1 root root 512K Feb 12 14:51 bootmgr.exe -rw-r--r-- 1 root root 0 Feb 12 14:57 empty lrwxrwxrwx 1 root root 11 Feb 12 14:51 pxeboot.0 /tftproot/winpe/Fonts: -rw-r--r-- 1 root root 47K Feb 12 14:56 wgl4_boot.ttf
Menu Entry
The menu entry may be constructed differently in your /tftproot/pxelinux.cfg/default file then mine. Just make sure the kernel line looks the same.
#display menu DEFAULT menu.c32 PROMPT 0 MENU TITLE My PXE Boot Menu TIMEOUT 150 TOTALTIMEOUT 900 label Localboot localboot -1 label w7x64 menu label Windows Install kernel winpe/pxeboot.0 keeppxe
TFTP Configuration
I would recommend using the tftp-hpa TFTP server because it allows you to map certain paths to other things. This is useful to map \boot to /winpe. Create a file called /etc/tftpd.map and add the content below to it. Make sure your TFTP server is set to start when the OS boots up.
re ^bootmgr\.exe windows/7/bootmgr.exe re ^\\boot\.ini windows/7/empty re ^\\hiberfile.sys windows/7/empty r ^\\Boot\\ windows/7/ r ^\\boot\\ windows/7/ r ^Boot/ windows/7/ r ^boot/ windows/7/ r ^/Boot/ windows/7/ r ^/boot/ windows/7/ r ^\\ windows/7/ rg \\ /
If you are using Gentoo, edit your /etc/conf.d/in.tftpd file and add -m /etc/tftpd.map to the INTFTPD_OPTS variable. It should look something like this:
INTFTPD_OPTS="-c -R 4096:32767 -s ${INTFTPD_PATH} -m /etc/tftpd.map"