pxe boot windows 7 from debian network boot
Technology Blog
Some little facts on technology related issues.
Search
Main menu
Skip to primary content
Skip to secondary content
Home
Post navigation
← Previous Next →
PXE Boot (Windows / Linux)
Posted on November 15, 2011
Installing operating systems using PXE boot is handy if you have a physical computer without a drive or you do not want to waste a CD or DVD. In order to perform a PXE boot, you need a PXE boot server. I created a virtual machine with Debian Squeeze that will serve as my PXE server.
First configure your network card to use an IP address in an own created network (e.g. 192.168.123.0/24) in order to prevent conflictions with your existing DHCP server/router. This can be done by uncommenting the dhcp line in /etc/network/interfaces by the following:
1
2
3
4
5
#iface eth0 inet dhcp
iface eth0 inet static
address 192.168.123.1
netmask 255.255.255.0
broadcast 192.168.123.255
Normally it should be enough to restart your networking (“service networking restart”) but I had to reboot the server so that the networking was correct. Make sure you can still access your machine. For a virtual machine, this is no problem since you have a console view but a remote server might not be accessible anymore. I used two network adapters in my virtual machine, where the second adapter (eth1) is in my network and accepts my ssh connections.
Then install and configure the DHCP server:
1
2
3
apt-get install dhcp3-server
mv /etc/dhcp/dhcpd.conf /etc/dhcp/dhcpd-original.conf
vim /etc/dhcp/dhcpd.conf
My dhcpd.conf looks like the following. The pxelinux.0 is the file that will be used for the PXE boot.
1
2
3
4
5
6
7
8
9
10
11
12
13
default-lease-time 86400;
max-lease-time 604800;
authoritative;
subnet 192.168.123.0 netmask 255.255.255.0 {
range 192.168.123.10 192.168.123.49;
filename "pxelinux.0";
option subnet-mask 255.255.255.0;
option broadcast-address 192.168.123.255;
option routers 192.168.123.1;
next-server 192.168.123.1;
}
Note: make sure you declare the “next-server” statement. I first omitted this statement and it worked on an earlier PXE server I created. This time, on the Debian Squeeze version, I was getting the “TFTP download failed” on my PXE client when I chose to boot windows (see further). After troubleshooting with wireshark, I noticed that the PXE client was requesting bootmgr.exe to IP address 0.0.0.0 instead of 192.168.123.1. This was resolved by specifying the TFTP server’s IP address (which is the same as our DHCP server) in the next-server statement.
After the installation and configuration of the DHCP server, restart it. It should not mention ‘Failed’, it might have when you installed the dhcp3-server package.
service isc-dhcp-server restart
Now install the TFTP server. I currently use the HPA’s TFTP server and used /srv/tftp as TFTP root directory:
apt-get install tftpd-hpa
Afterwards download the netboot archive for the Linux flavor you want to install. I chose the Debian Squeeze, but you can also choose something else. It should be easy to find the netboot.tar.gz for your Linux flavor. Here are a few for the (currently) recent Debian and Ubuntu releases:
Debian Squeeze amd64: http://ftp.nl.debian.org/debian/dists/squeeze/main/installer-amd64/current/images/netboot/netboot.tar.gz
Debian Squeeze i386: http://ftp.nl.debian.org/debian/dists/squeeze/main/installer-i386/current/images/netboot/netboot.tar.gz
Ubuntu Oneiric Ocelot (11.10) amd64: http://archive.ubuntu.com/ubuntu/dists/oneiric/main/installer-amd64/current/images/netboot/netboot.tar.gz
Ubuntu Oneiric Ocelot (11.10) i386: http://archive.ubuntu.com/ubuntu/dists/oneiric/main/installer-i386/current/images/netboot/netboot.tar.gz
Download this netboot.tar.gz and unpack it in your TFTP root directory (/srv/fttp):
1
2
3
cd /tmp
wget http://ftp.nl.debian.org/debian/dists/squeeze/main/installer-amd64/current/images/netboot/netboot.tar.gz
tar xzf netboot.tar.gz -C /srv/tftp/
That is it for the PXE boot server with one Linux distribution. You can test this using a PXE client machine. Make sure it is the same network. On a physical network, the client should be on the same switch/router as the PXE server. In a virtual environment, the client should be in the same subnet (e.g. if your PXE server is in NAT, you should put your PXE client in NAT also. My PXE server was a virtual machine and the client was a physical machine. In order to be in the same subnet, I had to place the PXE server in “bridge mode” and both the host and client were on the same switch.
Once you boot the client, an IP address in the 192.168.123.10-49 range should be received. An installation window for your chosen Linux should start.
Now, if we want to have the option to install different Linux distribution, we should add these. In order to do this in an organizational manner, we move the current ‘debian-installer’ directory to debian/squeeze as follows:
1
2
3
cd /srv/tftp
mkdir debian
mv debian-installer debian/squeeze
Update all the links to the debian-installer map to make sure the current setup still works:
1
2
3
4
5
6
grep -lr -e 'debian-installer' /srv/tftp/debian/squeeze/* | xargs sed -i 's/debian-installer/debian\/squeeze/g'
rm pxelinux.0
cp debian/squeeze/amd64/pxelinux.0 pxelinux.0
rm pxelinux.cfg
mkdir pxelinux.cfg
vim pxelinux.cfg/default
When we offer choices for the installation of the PXE client, we change the /srv/tftp/pxelinux.cfg/default file as following:
1
2
3
4
5
6
7
8
9
DISPLAY boot.txt
DEFAULT debian_squeeze_amd64
LABEL debian_squeeze_amd64
config debian/squeeze/amd64/pxelinux.cfg/default
PROMPT 1
TIMEOUT 0
In /srv/tftp/boot.txt you can list the choices. It is like a ‘message of the day’ that will be displayed before the boot prompt:
1
2
3
4
5
+----------+
| Choices: |
+----------+
* Debian Squeeze AMD64: debian_squeeze_amd64
At this point, everything should still work when you test with the PXE client. The only difference is that you have to type ‘debian_squeeze_amd64′ before you will see the installation menu. Let’s download and configure an extra Linux installation, e.g. Ubuntu 11.10 amd64:
1
2
3
4
5
6
7
cd /tmp
rm netboot.tar.gz
wget http://archive.ubuntu.com/ubuntu/dists/oneiric/main/installer-amd64/current/images/netboot/netboot.tar.gz
tar xzf netboot.tar.gz
mkdir /srv/tftp/ubuntu
mv ubuntu-installer/ /srv/tftp/ubuntu/oneiric
grep -lr -e 'ubuntu-installer' /srv/tftp/ubuntu/oneiric/* | xargs sed -i 's/ubuntu-installer/ubuntu\/oneiric/g'
Adapt the /srv/tftp/pxelinux.cfg/default as following:
1
2
3
4
5
6
7
8
9
10
11
12
DISPLAY boot.txt
DEFAULT debian_squeeze_amd64
LABEL debian_squeeze_amd64
config debian/squeeze/amd64/pxelinux.cfg/default
LABEL ubuntu_oneiric_amd64
config ubuntu/oneiric/amd64/pxelinux.cfg/default
PROMPT 1
TIMEOUT 0
and /srv/tftp/boot.txt:
1
2
3
4
5
6
+----------+
| Choices: |
+----------+
* Debian Squeeze AMD64: debian_squeeze_amd64
* Ubuntu Oneiric (11.10) AMD64: ubuntu_oneiric_amd64
When you start your PXE client, you should see the boot prompt with above the content of your boot.txt. You are now able to chose between Debian Squeeze and Ubuntu Oneiric.
Update: You can boot an iso file using memdisk. This will load the entire iso in the memory of the PXE client. However, if you do not have sufficient memory on the PXE client, you can extract the iso on your PXE server. You need to set up a NFS server (apt-get install nfs-kernel-server) and export a share (/etc/exports).
I used the following in /etc/exports:
/srv/nfs 192.168.123.0/24(ro,async,no_root_squash,no_subtree_check)
and executed the following commands:
1
2
3
4
5
6
7
8
service nfs-kernel-server restart
mount -o loop -t iso9660 /location/of/ISO/RedHat_6_2.iso /media
mkdir -p /srv/tftp/rhel/6/amd64
mkdir -p /srv/nfs/rhel/6/amd64
cp /media/images/pxeboot/vmlinuz /srv/tftp/rhel/6/amd64
cp /media/images/pxeboot/initrd.img /srv/tftp/rhel/6/amd64
cp -R /media/* /srv/nfs/rhel/6/amd64
umount /media
The new content of /srv/tftp/pxelinux.cfg/default:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
DISPLAY boot.txt
DEFAULT debian_squeeze_amd64
LABEL debian_squeeze_amd64
config debian/squeeze/amd64/pxelinux.cfg/default
LABEL ubuntu_oneiric_amd64
config ubuntu/oneiric/amd64/pxelinux.cfg/default
LABEL redhat_6.2_amd64
kernel rhel/6/amd64/vmlinuz
append method=nfs:192.168.123.1:/srv/nfs/rhel/6/amd64/ lang=us keymap=us ip=dhcp ksdevice=eth0 noipv6 initrd=rhel/6/amd64/initrd.img ramdisk_size=10000
PROMPT 1
TIMEOUT 0
and lastly append the option to the boot.txt accordingly.
Until now we only have Linux distributions as a choice. Let’s see how we can include Windows into our PXE server. For this you need:
The image of the Windows version you wish to install
The Windows Automated Installation Kit (AIK) for Windows 7
A (temporary) Windows-based computer in order to create your own AIK. This can be another virtual machine.
Start the creation of your AIK by installing the Windows AIK Setup on your temporary Windows-based computer. I did this on a Windows XP virtual machine. In “C:\Program Files\Windows AIK\Tools\PETools” I created the file script.bat with the following content:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
@echo off
cls
REM Variables
echo Setting variables ...
REM the path to your WAIK installation
set WAIKPath=%ProgramFiles%\Windows AIK
echo Set WAIK directory to %WAIKPath%.
REM possible values are: x86, amd64 and ia64
set ARCH=x86
echo Set architecture to %ARCH%.
set PEPath=C:\winpe_%ARCH%
echo Set temporary working directory for Windows PE to %PEPath%.
set TFTPPath=C:\tftp\Boot
echo Set TFTP boot directory to %TFTPPath%.
REM Don't change this one!
set BCDStore=%TFTPPath%\BCD
echo Set BCD store to %BCDStore%.
echo All variables set!
echo.
REM Environment check
echo Checking for clean environment...
if not exist "%WAIKPATH%" set NoWAIK=1 && goto :end
if not exist "%WAIKPath%\Tools\PETools\%ARCH%" set NoARCH=1 && goto :end
if exist %PEPath% echo Temporary working directory not empty! Need to remove && rd %PEPath% /S
if exist %PEPath% echo Temporary working directory still not empty! Trying again ... && cd "%WAIKPath%\Tools\%ARCH%" && imagex /unmount %PEPath%\mount && rd %PEPath% /S /Q
if exist %PEPath% set NotClean=1 && goto :end
if exist %TFTPPath% echo TFTP boot directory not empty! Need to remove && rd %TFTPPath% /S
if exist %TFTPPath% set NotClean=1 && goto :end
if exist %BCDStore% echo BCD store existing! Need to remove && del /P %BCDStore%
if exist %BCDStore% set NotClean=1 && goto :end
echo.
REM WORK!
echo Starting real work now ...
cd "%WAIKPath%\Tools\PETools"
echo Copying PE-Files ...
call copype %ARCH% %PEPath%
echo Mounting Windows PE image ...
imagex /mountrw %PEPath%\winpe.wim 1 %PEPath%\mount
md %TFTPPath% > NUL
copy %PEPath%\mount\Windows\Boot\PXE\*.* %TFTPPath% > NUL
copy "%WAIKPath%\Tools\PETools\%ARCH%\boot\boot.sdi" %TFTPPath% > NUL
copy %PEPath%\winpe.wim %TFTPPath% > NUL
cd %PEPath%\mount\Windows\System32
bcdedit -createstore %BCDStore%
bcdedit -store %BCDStore% -create {ramdiskoptions} /d "Ramdisk options"
bcdedit -store %BCDStore% -set {ramdiskoptions} ramdisksdidevice Boot
bcdedit -store %BCDStore% -set {ramdiskoptions} ramdisksdipath \Boot\boot.sdi
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
bcdedit -store %BCDStore% -set %GUID% detecthal Yes
bcdedit -store %BCDStore% -set %GUID% winpe Yes
bcdedit -store %BCDStore% -set %GUID% osdevice ramdisk=[boot]\Boot\boot.wim,{ramdiskoptions}
bcdedit -store %BCDStore% -set %GUID% device ramdisk=[boot]\Boot\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%
pause
goto :exit
:end
if %NoWAIK%=1 echo "Your WAIK directory was not found. Execution aborted." && pause && goto :exit
if %NoARCH%=1 echo "Your Architecture doesn't seem to be right. Or at least it is not known by your WAIK installation. Execution aborted." && pause && goto :exit
if %NotClean%=1 echo "Your environment was not clean. Execution aborted." && pause && goto :exit
:exit
Make sure you adapt the variables in the beginning of the script. The most important one is the ARCH variable. If you are planning to install amd64, then you should adapt the value appropriately. Also note that you should create the AIK for amd64 on a amd64 installation, i.e. your temporary windows should be 64 bit too.
This script will, if everything went well, create some files in TFTPPath (“C:\tftp\Boot” if you did not change it). Create a ZIP file (“WindowsBootx86.zip”) with all the files in that directory and move the ZIP file to your PXE server. I placed it into /tmp directory.
1
2
3
4
5
6
7
8
cd /tmp
mkdir -p /srv/tftp/windows/7/x86
unzip WindowsBootx86.zip -d /srv/tftp/windows/7/x86
cd /srv/tftp/windows/7/x86
ln -s pxeboot.n12 startrom.0
ln -s winpe.wim boot.wim
cd /srv/tftp/windows/7
ln -s x86 default
Create a remap file (/srv/tftp/pxelinux.cfg/remap) for the Windows files. Note that this translation is independent of the choice of the user. Every bootmgr.exe will be translated to windows/7/default/bootmgr.exe. This results in the drawback that you can only boot x86 or amd64, i.e. with this approach the PXE client can only take the architecture that is available. That is also the reason I created a soft link “default” to “x86″. When I need amd64, I create the AIK and put them in windows/7/amd64 and redirect the soft link to this directory. Nothing else needs to be adapted.
1
2
3
4
5
6
7
8
9
10
11
12
re ^pxeboot\.n12 windows/7/default/pxeboot.n12
re ^pxeboot\.com windows/7/default/pxeboot.com
re ^pxeboot\.0 windows/7/default/pxeboot.n12
re ^bootmgr\.exe windows/7/default/bootmgr.exe
r ^\\Boot\\ windows/7/default/
r ^\\boot\\ windows/7/default/
r ^Boot/ windows/7/default/
r ^/Boot/ windows/7/default/
r ^boot/ windows/7/default/
r ^/boot/ windows/7/default/
r ^\\ windows/7/default/
rg \\ /
Change the configuration for the TFTP server, specifying the remap file (/etc/default/tftpd-hpa):
# /etc/default/tftpd-hpa
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="--secure -m /srv/tftp/pxelinux.cfg/remap"
Lastly we need to adapt the /srv/tftp/pxelinux.cfg/default and /srv/tftp/boot.txt as following:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
DISPLAY boot.txt
DEFAULT debian_squeeze_amd64
LABEL debian_squeeze_amd64
config debian/squeeze/amd64/pxelinux.cfg/default
LABEL ubuntu_oneiric_amd64
config ubuntu/oneiric/amd64/pxelinux.cfg/default
LABEL windows_7
MENU LABEL Windows 7
KERNEL windows/7/default/startrom.0
PROMPT 1
TIMEOUT 0
and
1
2
3
4
5
6
7
+----------+
| Choices: |
+----------+
* Debian Squeeze AMD64: debian_squeeze_amd64
* Ubuntu Oneiric (11.10) AMD64: ubuntu_oneiric_amd64
* Windows 7 x86: windows_7
Because of the creation of the remap file, we need to restart the TFTP daemon:
service tftpd-hpa restart
Booting up the PXE client will give 3 options. Choosing the windows_7 options will boot the PXE client into a small Windows 7 environment with a windows shell. From this windows shell you can start the installation of your target Windows installation. This is best done by creating a samba share (or using another Windows computer to make the share). Extract the image, mostly an ISO file, to the share and mount it on the PXE client by typing in the shell:
1
2
3
net use y: \\[IP of your share server]\[name of your share]
y:
setup.exe
This will mount the share as the y: drive. Starting the setup.exe, will start the installation of that operating system. There are possibilities to start this installation automatically so that no manual actions are required. This involves creating startup scripts etc.
Note: In order to install Windows XP, you need to correct some registry entries before, and fix the boot sector after you format and partition your hard disk using diskpart. For fixing the registry entries, check: http://support.microsoft.com/kb/931760
Before you partition the hard disk in Windows Vista or in Windows PE 2.0, modify the registry so that the partitions are created by using the Windows XP procedure. To do this, follow these steps:
1. Click Start, click Run, type regedit, and then click OK.
2. Locate and then click the following registry subkey:
HKEY_LOCAL_MACHINE\SYSTEM\CURRENTCONTROLSET\SERVICES\VDS\ALIGNMENT
3. On the Edit menu, point to New, and then click DWORD value.
4. Type LessThan4GB as the new entry name.
5. Right-click LessThan4GB, and then click Modify.
6. In the Edit DWORD Value dialog box, click Decimal.
7. In the Value data box, type 0, and then click OK.
8. Repeat steps 3 through 7 to add the following registry entries:
Between4_8GB
Between8_32GB
GreaterThan32GB
Each registry entry must have a value of 0.
9. Exit Registry Editor.
The boot sector can be fixed by running “bootsect /nt52 c:”.
References:
http://www.howtoforge.com/ubuntu_pxe_install_server
http://doomclaw.de/index.php/2009/08/18/installing-windows-7-with-a-pxe-boot-server/
http://www.msfn.org/board/topic/139654-install-windows-from-iso-after-booting-to-winpe-30-from-usb-hdd/
This entry was posted in Linux, Networking by olivier. Bookmark the permalink.
2 thoughts on “PXE Boot (Windows / Linux)”
Pingback: Installation automatisée de Windows 7 via PXE/Linux « Sèm pas d’aqui
Pingback: Installation automatisée de Windows 7 via PXE/Linux « Sèm pas d’aqui
Leave a Reply
You must be logged in to post a comment.
Proudly powered by WordPress
Comments
Post a Comment