KVM with iPXE in RHEL6

Published Wednesday, November 2, 2011 (500 words, 3 minutes to read).

A while ago I discovered the amazing iPXE project. It is a complete PXE implementation with lots of nifty features, based on the gPXE project. Redhat ships the gPXE firmware for qemu and KVM, and you might want to use iPXE instead as the iPXE project currently seems to be more active. The major features (copied from ipxe.org):

  • boot from a web server via HTTP
  • boot from an iSCSI SAN
  • boot from a Fibre Channel SAN via FCoE
  • boot from an AoE SAN
  • boot from a wireless network
  • boot from a wide-area network
  • boot from an Infiniband network
  • control the boot process with a script

First, download the source code:

espen@luft:~$ mkdir ~/git
espen@luft:~$ cd ~/git
espen@luft:~/git$ git clone git://git.ipxe.org/ipxe.git
Cloning into ipxe...
remote: Counting objects: 33376, done.
remote: Compressing objects: 100% (9193/9193), done.
remote: Total 33376 (delta 24642), reused 30782 (delta 22666)
Receiving objects: 100% (33376/33376), 8.02 MiB | 1.94 MiB/s, done.
Resolving deltas: 100% (24642/24642), done.
espen@luft:~/git$ cd ipxe/
espen@luft:~/git/ipxe$

Then change the general configuration file (src/config/general.h) to suit your needs. Use the #define and #undef to activate and deactivate various features such as VLAN support, DHCP support, etc. Below is a small part of the header file for you to see.

[...]
#define IWMGMT_CMD   /* Wireless interface management commands */
#define FCMGMT_CMD   /* Fibre Channel management commands */
#define ROUTE_CMD    /* Routing table management commands */
#define IMAGE_CMD    /* Image management commands */
#define DHCP_CMD     /* DHCP management commands */
#define SANBOOT_CMD  /* SAN boot commands */
#define LOGIN_CMD    /* Login command */
#undef  TIME_CMD     /* Time commands */
#undef  DIGEST_CMD   /* Image crypto digest commands */
#undef  LOTEST_CMD   /* Loopback testing commands */
#undef  VLAN_CMD     /* VLAN commands */
#undef  PXE_CMD      /* PXE commands */
#undef  REBOOT_CMD   /* Reboot command */
[...]

Now it’s time compile the firmware.

espen@luft:~/git/ipxe$ cd src/
espen@luft:~/git/ipxe/src$ make bin/virtio-net.rom
  [DEPS] arch/i386/drivers/net/undirom.c
  [DEPS] arch/i386/drivers/net/undipreload.c
  [DEPS] arch/i386/drivers/net/undionly.c
  [DEPS] arch/i386/drivers/net/undinet.c
[...]
  [BIN] bin/virtio-net.rom.bin
  [ZINFO] bin/virtio-net.rom.zinfo
  [ZBIN] bin/virtio-net.rom.zbin
  [FINISH] bin/virtio-net.rom
[...]
espen@luft:~/git/ipxe/src$

The firmware compiled successfully, and it is ready to use. Log onto the RHEL 6 node, and verify that you have installed the package gpxe-roms-qemu (qemu-kvm currently depends on gpxe-roms-qemu). The directory /usr/share/gpxe/ contains the gPXE boot roms from this package.

To use your custom iPXE boot firmware instead, you can build a new rpm package that contains the new rom - or you can simply replace /usr/share/gpxe/virtio-net.rom [gPXE] with your ~/git/ipxe/src/bin/virtio-net.rom [iPXE]. As least you will have iPXE boot firmware until the qemu-roms-qemu package is updated ;)

Make sure that your virtual machines are using the virtio network device driver, and you are all set:

[...]
<interface type='bridge'>
  [...]
  <model type='virtio'/>
</interface>
[...]

Your virtual machines will now be booted using the iPXE boot firmware. Have a look at the iPXE scripting documentation for more inspiration!