TL;DR: We still (apparently) need DOS to flash our firmware. Doing this the old way sucks and doesn’t scale. Read on for a network-based solution using PXE (via DHCP + TFTP) on Linux.
Wherefore art thou DOS?
I don’t know why, but some (most!) hardware manufacturers insist on continuing to require DOS to flash firmware. Even if I only needed to flash the BIOS on one machine, this is still a hassle for lots of reasons: I don’t run Windows (which is still the “easy” way to make a boot floppy), nor do I really care to compile a new FreeDOS build. Even if I decide to go one of those routes…I don’t have floppies (much less a floppy drive), so I’m forced (in the case of Microsoft Windows) to deal with spinning up a VM and making a virtualized floppy, or forced to deal with getting and compiling FreeDOS. Once I get that far, dumping that to a USB thumb drive, adjust my boot order to allow that, etc.
Now consider the task of dragging a thumb drive (or a handful of them) to literally hundreds of servers, each requiring manual BIOS re-configuration, attaching a monitor and keyboard, and someone to stand there and type at it. This doesn’t scale and introduces considerable possibility of human error.
So, instead, why not use what you (probably) already have at your disposal? PXE is widely used to initiate netboots (Kickstarting Red Hat Linux, Netinstall Ubuntu, rescue images, etc), which only requires a simple services to set up (DHCP+TFTP or bootp). Plenty of great articles describing getting those set up already exist, so I won’t clutter this up describing that too much, but I prefer TFTP (with an assumption of DHCP), so that’s what this article will reference.
Get a DOS image
If you want to make your own base image (as described above), be my guest and you can skip this part.
If you decide to track one down online, the problem I encountered is that all of the pre-existing DOS images I could find via Google were ISO 9660. The problem is, ISO 9660 is a read-only format, so you are unable to (easily) hack up the image to do what you need.
So, I’ve done that work for you, and done so using FreeDOS, as well as included a REBOOT.COM executable (thanks to Evan Miller) to allow automated rebooting — if you don’t remember the good old days, DOS doesn’t have a built-in “reboot” command.
Download this Basic DOS image to your Linux PXE server, or:
# wget http://people.mozilla.org/~jvier/DOS_BOOT.IMG
Let’s get to it.
On the above disk image, I’ve included a basic AUTOEXEC.BAT which will set up a 4MB RAMdisk as X: (generally, you will need to zip up parts due to space constraints), and you’ll probably want to tweak a few things (as well as copy your BIOS firmware ROM onto the boot image, if nothing else).
- Mount your DOS image to a loopback mount so you can edit it.
# mkdir mnt # mount -o loop DOS_BOOT.IMG ./mnt
- Zip up your firmware ROM & associated utilities. For example, for SuperMicro servers (the hardware I needed this for), you’ll have phlash16.exe (the flash utility), chkflash.com (utility to make sure the ROM applies to the motherboard), flash.bat (wrapper batch file for these two utilities), and the ROM bundle (e.g. for my X7DBE motherboard server, 7dbec208.rom & X7DB8_nvram.lst.C208). We’re going to pile all of that into a zip file and copy it to the mounted image:
# zip phlash16.exe chkflash.com flash.bat 7dbec208.rom X7DB8_nvram.lst.C208 ROM_BUNDLE.zip # sudo cp ROM_BUNDLE.zip ./mnt/
- If you want to automate, edit the AUTOEXEC.BAT. I’ve included commented-out lines (I had all but forgotten about “rem” comments before embarking on this task) which should give you a good guide as to what you should do. Basically, copy the zip file to the RAMdisk (X:), unzip it, run the flash utility, reboot.
@echo off PROMPT $P$G VERIFY ON BREAK ON SRDISK 4096 rem COPY *.ZIP x:\ rem x: rem a:\unzip -x *.zip rem flash.bat flash_rom_name.rom rem a:\reboot
If you’re not familiar with DOS batch syntax, you’ll want to delete all the “rem” words (which denote “comment” lines) from the beginning of the lines. However, I would suggest that, until you test, you should probably leave the “reboot” line commented out.
Also, change flash_rom_name.rom to the actual name of your ROM file (for my SuperMicro server above, this would be 7dbec208.rom)
- Unmount the image and copy it into place on your TFTP server (as I said before, I’m not going to get into the details of setting up a TFTP server here) in a subdirectory, if you’d like. In my case, I put it in a “DOS” subdir to keep the DOS stuff separate from my normal Linux images.
# sudo umount ./mnt # sudo mkdir /tftpboot/pxelinux.cfg/DOS # sudo cp DOS_BOOT.IMG /tftpboot/pxelinux.cfg/DOS/
- Copy your syslinux memdisk (which creates a RAM disk and allows booting of legacy OSes [like DOS] via disk image) into your tftp directory structure. I left it in the parent pxelinux.cfg directory, since it’s useful for other things and isn’t actually a part of DOS, anyway.
# sudo cp /usr/share/syslinux/memdisk /tftpboot/pxelinux.cfg/ # sudo chmod 755 /tftpboot/pxelinux.cfg/memdisk
- Now add a new PXE menu option for your DOS boot image. Add the following lines to your /tftpboot/pxelinux.cfg/default file (or the appropriate PXE menu file, if you’re doing something fancier). I labeled min “bf” for “BIOS Flash”; obviously, you go ahead and name yours whatever you want. Also, if you normally attempt to PXE boot with a short timeout and/or no boot prompt, don’t forget to tweak the timeout to be long enough that you can easily ‘catch’ it (such as timeout 1000) and have a prompt (add option prompt 1).
label bf kernel memdisk bigraw append initrd=DOS/DOS_BOOT.IMG
- Now, assuming your host can see the TFTP server and is set to attempt to PXE you should be good to go. Just enter bf at the boot: prompt and it should fire up. If you’ve set up the automated bits in the AUTOEXEC.BAT, you should see them kick off; otherwise, you’ll be greeted with a both entertaining and sadly anachronistic “A:\>” prompt from which you can fire off all those DOS commands you have long forgotten.