Setting up PXE boot with qemu
I was expecting to spend the whole afternoon getting a tftp server setup so I could PXE boot some qemu virtual machines for testing. I wanted to make sure it didn’t interfere with anything else on the LAN so it would have to be limited to the user mode network I use with my vms. Typically when I try to do something like this I end up trying a bunch of different things that don’t quite work right. Today was the exception. I started out by reading the qemu manpage, which is very verbose but full of great information.
I was surprised to find that qemu has a built in tftp server! So to make sure I don’t forget about this, and to help out anyone else in the same situation, here’s what I did:
Create a local directory to hold the tftp and PXE related files, and copy over the syslinux files used by the PXE server.
mkdir -p ~/configs/tftp/pxelinux.cfg cp /usr/share/syslinux/*c32 ~/configs/tftp/ cp /usr/share/syslinux/pxelinux.0 ~/configs/tftp/
Create a basic menu that will boot the local harddrive, use this to test the
setup and see if it is working. Put the following into
default menu.c32 prompt 0 timeout 120 menu title PXE Menu label local menu label Boot from ^local drive localboot 0xffff
I use a script to startup my qemu vm’s with serial console, and random number generator setup. Put the following into a file and set it to executable:
#!/bin/sh qemu-kvm -cpu host -accel kvm \ -netdev user,id=net0,net=192.168.88.0/24,tftp=$HOME/configs/tftp/,bootfile=/pxelinux.0 \ -device virtio-net-pci,netdev=net0 \ -object rng-random,id=virtio-rng0,filename=/dev/urandom \ -device virtio-rng-pci,rng=virtio-rng0,id=rng0,bus=pci.0,addr=0x9 \ -serial stdio -boot n $@
When you run it with
run-qemu -m 4096 -hda /path/to/disk you should see the
PXE menu show up, and if you select the option to local boot it will try to
-hda that you have passed to it.
To boot a kernel+initrd put the vmlinuz and initrd.img files into a directory
~/configs/tftp/fedora32/, and add the following
section to the
default menu file in
label fedora32 kernel /fedora32/vmlinuz append initrd=/fedora32/initrd.img console=ttyS0```
If you are using the
initrd.img from a Fedora/RHEL/CentOS
boot.iso you can
boot the installer image by also appending
ip=dhcp inst.repo=http://HTTP-SERVER-IP-ADDRESS/fedora32/os/, but make sure you boot the VM with
more than enough ram for the image and the install since all if it will be
running from RAM – typically 4GB is enough.
The first version of this post referred to the configuration directory as
pxeboot.cfgwhich was incorrect. It should have been