Updating BIOS firmware via iPXE

      No Comments on Updating BIOS firmware via iPXE

These days mainboards usually come with some sort of wizbang tool that allow the user to update the BIOS from a USB drive or straight via network. Except, of course, that one single mainboard that absolutely needs a new BIOS version on a late Friday afternoon. And obviously the manufacturer only provides a flash tool for DOS and the mainboard is not supported by flashrom yet.
In those cases booting FreeDOS can be really handy. Booting FreeDOS via PXE is not that hard and it can also be booted via iPXE quite easily. If you do boot it via PXE, the easiest way to access the mainboard manufacturer’s flash tool and the new BIOS firmware from within FreeDOS is probably to include it in the PXE image file (see here). With iPXE however there’s a much more elegant way…

Minimal iPXE script to boot FreeDOS

While a comprehensive tutorial on how to set up a dhcp, tftp and iPXE server would go beyond the scope of this post, here’s a short outline of the necessary steps involved.
First, we need to configure the dhcp server so that the iPXE firmware is handed out to legacy PXE clients, and an iPXE boot configuration file is handed out to actual iPXE clients. With the ISC dhcp server this can be done by handing out different configurations based on the DHCP user class (see also http://ipxe.org/howto/dhcpd):

  if exists user-class and option user-class = "iPXE" {
      filename "http://my.web.server/freedos.ipxe";
  } else {
      filename "undionly.kpxe";

Of course the tftp server now needs to be configured to hand out undionly.kpxe which is part (at least on RHEL and Fedora) of the ipxe-bootimgs package. A very basic installation could look like this:

dnf install tftp-server ipxe-bootimgs
cp /usr/share/ipxe/undionly.kpxe /var/lib/tftpboot/
systemctl enable tftp.service
systemctl start tftp.service

Copying undionly.kpxe to /var/lib/tftpboot/ is necessary since the tftp daemon is started in secure mode per default which disables following symlinks.

A minimalistic freedos.ipxe boot configuration file could be


kernel memdisk raw
initrd http://www.freedos.org/download/download/FD12FLOPPY.zip
boot || goto failed

echo Booting failed, dropping to shell
goto shell

The memdisk kernel is part of the syslinux-tftpboot package. Creating a symlink to /tftpboot/memdisk in the same directory in which the freedos.ipxe boot configuration file lives should be sufficient.

iPXE booting FreeDOS

Creating a payload image

Instead of manipulating the FreeDOS floppy image to include the mainboard manufacturer’s flash tool and the BIOS update file, we’re going to create a separate payload image and attach it to FreeDOS as an additional hard disk.

First, we’ll create an empty 32MB file (which could be bigger if one needed more space) and partition it with the first partition starting at LBA Address 63

truncate payload.img --size 32MB
sfdisk payload.img << EOF

Next, set up the resulting payload.img file as loop device and create a filesystem:

losetup /dev/loop0 payload.img
mkfs.vfat /dev/loop0p1 

If there’s no separate device for the first partition (e.g. /dev/loop0p1 you might want to pass a max_part option to the loop kernel module module so that loop devices are partitionable:

modprobe -r loop
modprobe loop max_part=16

Now you can mount the partition and copy the necessary files (flash tool and BIOS firmware)

mount /dev/loop0p1 /mnt/ 
cp <necessary files> /mnt/
umount /mnt
losetup -d /dev/loop0 

Attaching the payload image as additional hard drive

The only thing left to do is to attach the newly created payload image as an additional hard disk to FreeDOS:


sanhook payload.img || goto failed
kernel memdisk raw
initrd http://www.freedos.org/download/download/FD12FLOPPY.zip
boot || goto failed

echo Booting failed, dropping to shell
goto shell

Don’t forget to copy the payload.img to the host handing out the freedos.ipxe iPXE boot configuration file.

FreeDOS bootin with additional hard disk attached via sanhook

After booting up FreeDOS you can find the contents of the payload image file under C: (or D: if you booted the FreeDOS cdrom images instead of the floppy image).

Leave a Reply

Your email address will not be published.