Skip to main content

Updating your server BIOS using FreeDOS and GRUB

In this post I am explaining the steps you can follow to boot from a DOS image using your grub to update the server’s BIOS version without the need of using a USB drive attached to your server.

To check your BIOS version in your server run this command:

$ sudo dmidecode --type bios
# dmidecode 2.12
SMBIOS 2.6 present.

Handle 0x0000, DMI type 0, 24 bytes
BIOS Information
	Vendor: Dell Inc.
	Version: 1.12.0
	Release Date: 07/30/2013
	Address: 0xF0000
	Runtime Size: 64 kB
	ROM Size: 4096 kB
	Characteristics:
		ISA is supported
		PCI is supported
		PNP is supported
		BIOS is upgradeable
		BIOS shadowing is allowed
		Boot from CD is supported
		Selectable boot is supported
		EDD is supported
		Japanese floppy for Toshiba 1.2 MB is supported (int 13h)
		5.25"/360 kB floppy services are supported (int 13h)
		5.25"/1.2 MB floppy services are supported (int 13h)
		3.5"/720 kB floppy services are supported (int 13h)
		8042 keyboard services are supported (int 9h)
		Serial services are supported (int 14h)
		CGA/mono video services are supported (int 10h)
		ACPI is supported
		USB legacy is supported
		BIOS boot specification is supported
		Function key-initiated network boot is supported
		Targeted content distribution is supported
	BIOS Revision: 1.12

Handle 0x0D00, DMI type 13, 22 bytes
BIOS Language Information
	Language Description Format: Long
	Installable Languages: 1
		en|US|iso8859-1
	Currently Installed Language: en|US|iso8859-1

Now we are going to make a small bootable DOS system that we will use to boot in the server. I did the following steps in my own PC, but you can do them anywhere.

Install qemu if not installed yet to be able to install FreeDOS:

# apt-get update
# apt-get install syslinux qemu-system-x86

You can download FreeDOS here http://www.freedos.org/download/

or just:

$ wget http://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/distributions/1.0/fdbasecd.iso

Creaty an empty image of 250MB size:

dd if=/dev/zero of=fdos-250m-hdd.img bs=1M count=250

Launch qemu and install FreeDOS into the empty image:

qemu-system-x86_64 -hda fdos-250m-hdd.img -cdrom fdbasecd.iso -boot d

After installing FreeDOS you have to copy the BIOS updater tool to the image. To do that follow this steps:

~# fdisk -ul fdos-250m-hdd.img
GNU Fdisk 1.2.5
Copyright (C) 1998 - 2006 Free Software Foundation, Inc.
This program is free software, covered by the GNU General Public License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.


Disk /home/user/fdos-250m-hdd.img: 261 MB, 261660672 bytes
16 heads, 63 sectors/track, 507 cylinders, total 511056 sectors
Units = sectors of 1 * 512 = 512 bytes

                          Device Boot      Start         End      Blocks   Id  System 
/home/user/fdos-250m-hdd.img1   *          63      511055      255496    e  FAT16 LBA

The partition starts at 63, so to get the offset, we have to multiply 63 by 512, 32256. To mount the partition you have to run this command:

~# mount -o loop,offset=32256 fdos-250m-hdd.img /mnt/

And copy the required tool:

~# mkdir /mnt/DELL
~# cp PER410-011200.exe /mnt/DELL/
~# umount /mnt

Once you have your FreeDOS image ready, copy the image to your server to /boot/images. Create the directory /boot/images if it does not exist.

Prepare grub2 to use memdisk

$ sudo cp -a /usr/lib/syslinux/memdisk to /boot

Create the following file with your preferred editor:

~# cat /etc/grub.d/50_memdisk 
#!/bin/sh

set -e

IMAGES=/boot/images
. /usr/lib/grub/grub-mkconfig_lib
if test -e /boot/memdisk ; then
  MEMDISKPATH=$( make_system_path_relative_to_its_root "/boot/memdisk" )
  echo "Found memdisk: $MEMDISKPATH" >&2
  find $IMAGES -name "*.img" | sort | 
  while read image ; do
      IMAGEPATH=$( make_system_path_relative_to_its_root "$image" )
      echo "Found floppy image: $IMAGEPATH" >&2
      cat << EOF
menuentry "Bootable floppy: $(basename $IMAGEPATH | sed s/.img//)" {
EOF
      prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/"
      cat << EOF
        linux16 $MEMDISKPATH bigraw
        initrd16 $IMAGEPATH
}
EOF
  done
fi

And finally update grub with your new image:

$ sudo update-grub
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-3.13.0-68-generic
Found initrd image: /boot/initrd.img-3.13.0-68-generic
Found memtest86+ image: /memtest86+.elf
Found memtest86+ image: /memtest86+.bin
Found memdisk: /memdisk
Found floppy image: /images/fdos-250m-hdd.img
done

Reboot and boot from your new image.