Reference for making Windows (10) boot from network/PXE i.e. inside KVM/QEMU
The purpose of this collection of script is to capture the process of network booting the Windows in particular WinPE. Tested on Windows 10 (19H2), but should work on any Windows10+ eventually also for older versions but that might need some tweaks.
- tftp/simple.ipxe - to switch from TFTP to HTTP
- web/next.ipxe - the next stage loaded over HTTP
web/wimboot
- the magic wimboot (bootloader, download at: https://github.com/ipxe/wimboot/releases)web/boot/bcd
- the boot config (registry hive, get from WinPE ISO)web/boot/bcd.sdi
- the ramdisk (X: drive, get from WinPE ISO)web/sources/winpe.wim
- the actuall Windows PE (expanded into X:, get from WinPE ISO)
Section on making WinPE ISO.
The just start the:
- make the network switch for testing
brhost
- dnsmasq (host) - DHCP + DNS + TFTP server, listen on
brhost
IP - nginx web server (dockerized) - HTTP SERVER, listen on
brhost
IP - kvm/qemu to test (see example at the end of this file)
Transient network:
BRN=brhost
OIF=eth0
# make device
ovs-vsctl add-br $BRN
# set device up
ip link set dev $BRN up
# set ip
ip address add 192.168.100.1/24 dev $BRN
# Optional: configure forwarding and SNAT
iptables -I FORWARD -i $BRN -o $OI -j ACCEPT
iptables -I FORWARD -o $BRN -i $OI -j ACCEPT
iptables -t nat -I POSTROUTING -o $OIF -j MASQUERADE
# you might need to change '-I' to '-A' eventually
# in case you have bridge traffic filtered in some way
# /etc/sysctl.d/50-no-bridge-iptables.conf
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0
# sysctl -p /etc/sysctl.d/50-no-bridge-iptables.conf
# to turn that filtering off completely - just for testing
# in other cases you might need to tweak the rules in a way
# that it let through the legitimate traffic
# this might become complex :-) with IPv4/6 and ARP
Principal steps:
- Get
winpe.wim
more,boot.wim
orinstall.wim
from install ISO/CDROM @\sources\boot.wim
or\sources\install.wim
- Configure and run
DHCP
andHTTP
servers (good tip is to usednsmasq
,nginx
and optionallyphp-fpm
) - Test everything with KVM/QEMU (boot>network)
- Use on your network as needed
Microsoft on boot process
Note: The WinPE is a base Windows Image, that can turn into install, WinRE or other purpose short-lived instance of windows, with limited capabilities (i.e. w/o USERs, extra SW). There is a option to customize the bare image using winpeshl.ini an example and/or startnet.cmd
You might find useful to manipulate the *.wim
images using dism
The magic is done by wimboot for technical internals check the ipxe.org/wimboot web.
The way to build the virsh image can be following:
#!/bin/bash
set -x
set -e
VM_NAME=wimtest
VM_CPU=1
VM_NET_NAME=brhost
VM_NIC_MAC=52:54:00:00:00:01
VM_RAM=2048
virt-install \
--dry-run \
--import \
--print-xml \
--name=${VM_NAME} \
--arch=x86_64 \
--vcpus=${VM_CPU} \
--cpu=host \
--os-type=windows \
--os-variant=win10 \
--network bridge=${VM_NET_NAME},mac=${VM_NIC_MAC},model=virtio \
--graphics vnc,listen=127.0.0.1,port=5900 \
--hvm \
--video model=virtio,model.vram=16384 \
--ram=${VM_RAM} \
--boot network \
| tee vm.xml
That yields file similar to vm.xml.
You might find useful to add the target disk image for installation or floppy with drivers or iso with drivers. Eventually the second ISO with install files if not using the SMB share. You can also benefit from WinPE to dism /Image-Apply
a wim
file to the target disk. It is fast and convenient. Please do not forget to fix, update the MBR
, partition bootsect
or EFI
partition as needed to make the disk bootable.
The network booting can be complicated. There are at least two boot environments the BIOS and UEFI. Not taking into account the CoreBoot (former LinuxBoot). The initial test environment was BIOS based KVM virtual machine.
The common issue is also gathering the correct files based on your PXE environment.
It migh be pxelinux.0
, undi.kpxe
, boot32.efi
, boot64.efi
. Also the subsequent stage wimboot
requires few files from windows install ISO
like bcd
, bcd.sdi
. Some other files are used directly from the WIM
file.