PXE booting for BIOS updates
So you're all about the free software. But you've just obtained a new (or old) machine. And its firmware is out of date and in need of updates. It doesn't have a floppy drive, just a CD or DVD drive and USB hard drive support. There aren't any copies of DOS or Windows in the house that might be used to for a firmware update. Ah, but it will netboot!
set up DHCP to point net-booting machines at a TFTP server
Here's an /etc/dhcp/dhcpd.conf stanza for the to-be-updated machine:
host yesdear { hardware ethernet 00:1a:a0:25:fc:f3; fixed-address 172.16.0.150; option host-name "yesdear"; next-server 172.16.0.1; filename "pxelinux.0"; }
The "next-server" keyword tells the client machine which TFTP server to contact. And the "filename" keyword tells it which file to download from that TFTP server.
install a TFTP server
TFTP is the "trivial file transfer protocol" defined in RFC 1350 (and others). It's a UDP based mechanism often used to get boot images over a network.
I'm running the "atftpd" TFTP server. It's home on the web seems to be ftp://ftp.mamalinux.com/pub/atftp/
Running Debian, atftpd is installed with the command apt-get install atftpd
. The package maintainer scripts will add an entry to /etc/inetd.conf and will create a directory called /var/lib/tftpboot from which atftpd will serve files.
Setting up pxelinux and create a config file
installing pxelinux
PXElinux is part of syslinux. Install it thusly:
apt-get install syslinux install -o root -g root -m 444 /usr/lib/syslinux/pxelinux.0 /var/lib/tftpboot/pxelinux.0
a PXElinux config file
The config file telling PXElinux what to do is also fetched from the TFTP server by the client machine. The config files live in the pxelinux.cfg
directory under the TFTP server's root. For us, this will be /var/lib/tftpboot/pxelinux.cfg
. PXElinux tries to fetch a number of config files in turn. This process is documented in /usr/share/doc/syslinux/pxelinux.txt.gz
. For our purposes, we'll just be setting up the default
config file. It reads like so:
label dos kernel memdisk append initrd=fdboot.img
This config file instructs PXElinux to load the memdisk driver from the TFTP server instead of a Linux kernel. And it tells the memdisk driver to read in the fdboot.img file from the TFTP server to use as a fake disk drive.
The memdisk driver is part of the syslinux distribution and must be copied to the TFTP server's root directory before the client can load it:
install -o root -g root -m 444 /usr/lib/syslinux/memdisk /var/lib/tftpboot/memdisk
syslinux's memdisk module
The syslinux memdisk module can load a disk image over the network and create a RAM-backed virtual floppy or hard drive. For our purposes, a floppy will perform nicely. Most BIOS updates are pretty small files (1.8Mbytes for our Dell GX740 update). memdisk assumes that images smaller than 4Mibytes are floppies. We'll be creating a 3840kibyte floppy image and putting FreeDOS and the BIOS update on it. The floppy image will be stored in /var/lib/tftpboot/fdboot.img
. Complete documentation for the memdisk module can be found in /usr/share/doc/syslinux/memdisk.txt.gz
.
create a floppy image to netboot
What goes in to our floppy disk image? We'll want a formatted floppy, enough DOS present to make it bootable, and the BIOS updater image. mtools is a suite of programs for dealing with DOS disks and includes a program for formatting disks. FreeDOS is a free implementation of the MS-DOS/PC-DOS ABIs (which is to say that it's a DOS clone). And the BIOS updater image is available from your PC's maker's website (hopefully).
Get FreeDOS bits
Download the FreeDOS installation ISO image from http://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/distributions/1.0/fdfullcd.iso. We'll be pulling three files out of there to put into our virtual floppy disk to make it bootable. Mount the ISO image somewhere convenient, like so:
mount -v -o loop,ro /tmp/fdfullcd.iso /mnt
Make a little holding directory for the files we need:
mkdir /tmp/freedos_boot_files
And copy the FreeDOS FAT12 boot sector, the FreeDOS kernel, and the FreeDOS shell (command.com) to our holding directory:
# The FAT12 boot sector is in a .ZIP archive unzip -p /mnt/freedos/packages/src_base/kernels.zip \ source/ukernel/boot/fat12.bin \ > /tmp/freedos_boot_files/fat12.bin # Odin is a single-disk version of FreeDOS cp /mnt/freedos/setup/odin/kernel.sys /tmp/freedos_boot_files/ cp /mnt/freedos/setup/odin/command.com /tmp/freedos_boot_files/
Use mtools to format
Now that we've got enough pieces of FreeDOS to run the BIOS updater, we'll need to create the floppy disk image to boot from. Annoyingly, mtools refers to disk drives instead of paths to image files, so we'll point mtools's Z: drive at a floppy image and refer to the floppy image as Z: when we use mtools programs to manage it.
- update /etc/mtools.conf:
First off, we need to define Z: in our /etc/mtools.conf. Here's what I have for it:
drive z: file="/tmp/fdboot.img" fat_bits=12
The "fat_bits=12" bit tells mtools to always use a 12-bit FAT filesystem on drive Z:. FAT12 is used on floppies, while FAT16 is seen on hard disk partitions. I've found no other way to insist that the filesystem creator command (mformat) use a 12-bit FAT.
- Format it!
mformat -C -t 80 -n 48 -h 2 -B /tmp/freedos_boot_files/fat12.bin z:
Some explanation is in order: 80 tracks, 2 sides, 48 sectors per track. Use the FreeDOS FAT12 boot sector. "-C" says that it's OK if the image file for the Z: drive needs to be created. 80 tracks * 2 sides * 48 sectors per track gets us 7680 sectors on this disk image or 3840Kibytes of data (512 bytes per sector)
copy FreeDOS programs into floppy image
mcopy /tmp/freedos_boot_files/kernel.sys z: mcopy /tmp/freedos_boot_files/command.com z: mattrib +r +h +s z:kernel.sys mattrib +r z:command.com
copy BIOS updater into floppy image
O740-225.EXE is a Dell Optiplex GX740 BIOS update. It has been downloaded to /tmp. Copy it into our floppy image like so:
mcopy /tmp/O740-225.EXE z:
Put the floppy image into the TFTP server's root directory
install -o root -g root -m 444 /tmp/fdboot.img /var/lib/tftpboot
boot client machine
Tell it to PXE boot. Tell PXElinux to load the "dos" image. Get dumped into a COMMAND.COM session. Run the BIOS updater.