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
~/configs/tftp/pxelinux.cfg/default
1:
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
boot the -hda
that you have passed to it.
To boot a kernel+initrd put the vmlinuz and initrd.img files into a directory
under ~/configs/tftp/
like ~/configs/tftp/fedora32/
, and add the following
section to the default
menu file in pxelinux.cfg/
:
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.cfg
which was incorrect. It should have beenpxelinux.cfg
↩︎