I would like to make a "massive" DOS floppy disk image, say 10MB or more, containing all the firmware updates I need for any system, hard drive or BIOS.

I do not need the DOS image to be network-able as everything will be on the PXE-booted image, but networking would be nice. Since Zip Disks were attached to the floppy disk controller and were over 100MB, this should be possible.

I tried a long time ago to do this and spent too much time on it only to have it fail to boot. So if someone has reliable instructions on how to create such a nightmarish beast and edit it, please let me know. An image that can be used for PXE and copied to a USB stick would be a plus.

Too bad manufacturers don't supply a single bootable Linux ISO containing all their firmware updates that would be easy to boot over-the-LAN and have networking. HP servers do this and it is awesome.

  • I don't know the answer but you should check Hiren's Boot CD (or USB stick) and check the different images and boot options that they have there
    – golimar
    Jun 29, 2012 at 9:12
  • 1
    I couldn't agree more. It's just ridiculous!
    – hookenz
    Oct 3, 2013 at 2:47
  • 1
    @vallismortis - what are you wholeheartedly disagreeing on? I was commenting on it being ridiculously difficult to deploy bios updates and so forth especially on servers etc. But many manufacturers still provide their update utilities for DOS. Downloading DOS and getting it to work on a USB stick is hard. Who runs DOS? they should provide these utilities on Linux.
    – hookenz
    Aug 5, 2018 at 22:28
  • 1
    @MattH I am so sorry - I thought you were criticizing the question. Oops! Comment deleted.
    – Parker
    Aug 6, 2018 at 12:18

4 Answers 4


You can make a FreeDOS bootable image (any size you need) for your purposes and then add any software or any DOS utility like BIOS update tools, etc.

From your question it seems you have access to Linux and might be familiar with using the terminal/command line. So for this answer I will focus on creating the bootable image in Linux. On a Windows machine you could use a tool like Rufus to do do this.

You can then boot of this FreeDOS image using PXE boot or write it to a USB drive with dd to create a FreeDOS boot drive. Ofcourse you can extend the steps used here to create any FreeDOS media you'd like including adding the full suite of software that comes with the FreeDOS Full edition.

Below are the steps for creating a bootable FreeDOS image in Linux:

WARNING / DISCLAIMER!!! Some commands used below have the potential to wipe data from your disk drives if used incorrectly. Read the man page for each program to understand the command usage before proceeding. You might want to try these commands on a secondary/virtual machine that doesn't have your valuable data on it.

Step 1: Install Prerequites (ms-sys):

  • Install ms-sys from source if its not available with your package manager:

    $ wget https://sourceforge.net/projects/ms-sys/files/ms-sys%20stable/2.6.0/ms-sys-2.6.0.tar.gz
    $ tar -xzvf ms-sys-2.6.0.tar.gz
    $ cd ms-sys-2.6.0
  • Compiling ms-sys requires msgfmt from the gettext package which can be installed on Debian/Ubuntu using:

    $ sudo apt install gettext
  • Compile and Install:

    $ make
    $ sudo make install

Step 2: Create a blank disk image and create a msdos partition:

  • Create an empty file for the disk image:

    $ truncate -s 50M disk.img

    Note: Here a 50 MiB size disk image is created but you can make this any size you need

  • Partition the disk image:

    $ fdisk disk.img
    Command (m for help): o
        Created a new DOS disklabel with disk identifier 0x1234abcd.
    Command (m for help): n
        Partition type
           p   primary (0 primary, 0 extended, 4 free)
           e   extended (container for logical partitions)
        Select (default p): p
        Partition number (1-4, default 1): <ENTER>
        First sector (2048-102399, default 2048): 2048
        Last sector, +sectors or +size{K,M,G,T,P} (2048-102399, default 102399): <ENTER>
    Command (m for help): t
        Selected partition 1
        Partition type (type L to list all types): c
    Command (m for help): a
        Selected partition 1
        The bootable flag on partition 1 is enabled now.
    Command (m for help): w

    Note: The fdisk commands above assume you want a FAT32 file-system. If you want to use a FAT16 file-system then for the question above Partition type (type L to list all types): enter e instead of c

Step 3: Confirm location of the starting sector of the first partition:

  • Use fdisk to determine the starting sector:

    $ fdisk -l disk.img
    Disk disk.img: 50 MiB, 52428800 bytes, 102400 sectors
    Units: sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disklabel type: dos
    Disk identifier: 0x1234abcd
    Device     Boot Start    End Sectors Size Id Type
    disk.img1  *     2048 102399  100352  49M  c W95 FAT32 (LBA)

    Note: From the above fdisk output we can see that the starting sector offset is 2048 sectors or 2048 x sector_size bytes = 2048 x 512 bytes = 1048576 bytes. Actually we explicitly specified the starting sector in Step 2 but I included this step as it might be useful when the partition was already created. These numbers: 2048 and 1048576 are used in the commands that follow.

Step 4: Format the partition with a FAT file-system

  • Search for a free loop device:

    $ losetup -f
  • Create a loop device of the partition (which is at offset=1048576 of the disk image):

    $ sudo losetup -o1048576 /dev/loop0 disk.img
  • Create FAT File System:

    • To create a FAT16 file system:

      $ sudo mkfs.vfat -F16 -R8 -h2048 /dev/loop0
    • To create a FAT32 file system:

      $ sudo mkfs.vfat -F32 -h2048 /dev/loop0

      Note: In the mkfs.vfat parameter -h2048 is required. mkfs.vfat doesn't write the hidden sectors before the partition to the boot record unless you specify this parameter and it is required for booting the image). Again here 2048 is the partition 1 offset in sectors as determined in Step 3. The parameter -R8 is optional but recommended.

Step 5: Use ms-sys to write to the Master Boot Record (MBR) and Volume Boot Record (VBR):

  • First write the VBR while the partition is still loaded as a loop device:

    • To create a FAT16 file system:

      $ sudo ms-sys --fat16free /dev/loop0
    • To create a FAT32 file system:

      $ sudo ms-sys --fat32free /dev/loop0


      • Don't use this command: ms-sys --partition /dev/loop0 even thought it is discussed in some of the ms-sys documentation as being required in some cases. It will overwrite the hidden sectors field already correctly written by mkfs.vfat
      • ms-sys only writes to the first boot record. ms-sys unlike Rufus does not write to FAT32's backup boot record but this shouldn't prevent the image from being bootable.
  • Next unload/detach the disk image file from the loop device:

    $ sudo losetup -d /dev/loop0
  • And finally write a Windows 7 MBR to the disk image:

    $ ms-sys --mbr7 --force disk.img

    Note: ms-sys requires the --force argument when writing to regular (non-device) files.

Step 6: Write Basic FreeDos files and any other programs you need to the partition on the disk image:

  • Mount partition:

    $ mkdir mnt
    $ sudo mount -o loop,offset=1048576 disk.img mnt/
  • Download and extract required FreeDOS files:

    $ wget https://github.com/pbatard/rufus/archive/v3.6.tar.gz
    $ tar -xvf v3.6.tar.gz rufus-3.6/res/freedos/

    Note: These files are downloaded from the Rufus github repository but are extracted from the official FreeDOS website. See the readme.txt on https://github.com/pbatard/rufus/tree/master/res/freedos/ for detail on were Rufus gets the binaries from the official FreeDOS sources.

  • Copy files to partition:

    $ sudo mkdir mnt/LOCALE
    $ sudo cp rufus-3.6/res/freedos/!(COMMAND.COM|KERNEL.SYS) mnt/LOCALE/
    $ sudo cp rufus-3.6/res/freedos/{COMMAND.COM,KERNEL.SYS} mnt/
    $ printf '@echo off\r\nset PATH=.;\\;\\LOCALE\r\necho Using US-English keyboard with US-English codepage [437]\r\n' | sudo tee mnt/AUTOEXEC.BAT
    $ sudo fatattr +h +s mnt/COMMAND.COM
    $ sudo fatattr +h +s mnt/KERNEL.SYS


    • The only files that are really required to make the disk image bootable are COMMAND.COM and KERNEL.SYS. The rest of the files are optional
    • You can now also copy any other files you have to the disk image as well before unmounting it (eg: BIOS firmware updates).
    • The fatattr commands are optional but add hidden and system attributes to the files COMMAND.COM and KERNEL.SYS as is customary. On a Debian/Ubuntu system you can install the fatattr program using sudo apt-get install fatattr

Step 7: You are Done!

  • Unmount the disk image:

    $ sudo umount mnt/

I've been through this process a few times, and although it is extremely easy, I keep forgetting the exact steps I used, so I am documenting it here for my own reference as well as others. For the record, I am using Slackware Linux 14.2+ as the PXE server, and booting to several different Dell Optiplex models for BIOS updates. As mentioned in other answers, you can create bootable ISO images for large filesystems. However, since you specifically asked about bootable floppy images, here are the steps I use for that.

First, some background information on MEMDISK and FAT12 to put your question in context. There is a lot of conflicting and ambiguous information out there, so hopefully this clears things up a bit.

A syslinux thread from 2003 indicates that MEMDISK supports a maximum image size of 4GB, depending on the hardware (i.e., memory-limited, but possibly additional hardware-specific considerations). An earlier thread from 2002 also indicates a separate PXELINUX limitation (Linux kernel space limited to ~1GB, but this information is over 15 years old).

From the MEMDISK documentation, there are some specific floppy disk geometries that memdisk will attempt to guess:

Floppy images

If the disk image is less than 4,194,304 bytes (4096K, 4 MiB) it is assumed to be a floppy image and MEMDISK will try to guess its geometry based on the size of the file. MEMDISK recognizes all the standard floppy sizes as well as common extended formats:

  163,840 bytes  (160K) c=40 h=1 s=8    5.25" SSSD
  184,320 bytes  (180K) c=40 h=1 s=9    5.25" SSSD
  327,680 bytes  (320K) c=40 h=2 s=8    5.25" DSDD
  368,640 bytes  (360K) c=40 h=2 s=9    5.25" DSDD
  655,360 bytes  (640K) c=80 h=2 s=8    3.5"  DSDD
  737,280 bytes  (720K) c=80 h=2 s=9    3.5"  DSDD
1,222,800 bytes (1200K) c=80 h=2 s=15   5.25" DSHD
1,474,560 bytes (1440K) c=80 h=2 s=18   3.5"  DSHD
1,638,400 bytes (1600K) c=80 h=2 s=20   3.5"  DSHD (extended)
1,720,320 bytes (1680K) c=80 h=2 s=21   3.5"  DSHD (extended)
1,763,328 bytes (1722K) c=82 h=2 s=21   3.5"  DSHD (extended)
1,784,832 bytes (1743K) c=83 h=2 s=21   3.5"  DSHD (extended)
1,802,240 bytes (1760K) c=80 h=2 s=22   3.5"  DSHD (extended)
1,884,160 bytes (1840K) c=80 h=2 s=23   3.5"  DSHD (extended)
1,966,080 bytes (1920K) c=80 h=2 s=24   3.5"  DSHD (extended)
2,949,120 bytes (2880K) c=80 h=2 s=36   3.5"  DSED
3,194,880 bytes (3120K) c=80 h=2 s=39   3.5"  DSED (extended)
3,276,800 bytes (3200K) c=80 h=2 s=40   3.5"  DSED (extended)
3,604,480 bytes (3520K) c=80 h=2 s=44   3.5"  DSED (extended)
3,932,160 bytes (3840K) c=80 h=2 s=48   3.5"  DSED (extended)

A small perl script is included in the MEMDISK directory which can determine the geometry that MEMDISK would select for other sizes; in general, MEMDISK will correctly detect most physical extended formats used, with 80 cylinders or slightly higher.

 LABEL floppy_image
  LINUX memdisk
  INITRD floppy.img

If your image is larger than 4 MiB and it is a floppy image, you can force MEMDISK to treat it as a floppy image:

 LABEL floppy_image
  LINUX memdisk
  INITRD floppy.img
  APPEND floppy

In practice, I haven't had any luck with the APPEND floppy parameter; I get a MEMDISK: No ramdisk image specified! error when I use it.

Traditionally, floppy images use the FAT12 format, which have a limit of 16MB and 8k clusters. There appear to be extensions to FAT12 that allow 32MB or even 256MB (64k clusters) but I am uncertain on the specifics.

If we target the maximum FAT12 size (16,736,256 bytes) for a bootable 'floppy' image, we can do the following:

dd if=/dev/zero of=FAT12_16MB.img bs=1 count=16736256

However, that command can take a minute to complete. Using a higher block size, we can accomplish the same thing in less than a second:

dd if=/dev/zero of=FAT12_16MB.img bs=8192 count=2043

Now that we have a 'blank floppy disk', we need to format it as FAT12 (if you are interested in the available parameters for this command, run man mkfs.fat to view the man page):

mkfs.fat -D 0x00 -F 12 -n FREEDOSBIOS FAT12_16MB.img

Now we have a formatted FAT12 'floppy disk' image. We can create a folder and mount it:

mkdir floppy
mount -t msdos -o loop FAT12_16MB.img floppy

And now we can start copying files to it. I downloaded the FreeDOS OEM Boot Disk from fdos.org and copied it to my larger image:

wget http://www.fdos.org/bootdisks/autogen/FDOEM.288.imz
unzip FDOEM.288.imz

Create a new mount point for the FreeDOS image and mount it:

mkdir freedos12
mount -t msdos -o loop FDOEM.288 freedos12

Copy the FreeDOS operating system to your larger floppy:

cp -r freedos12/* floppy

Then unmount the FreeDOS partition and delete the mount point if no longer needed:

umount freedos12
rmdir freedos12

Now we have a 16MB floppy image (FAT12_16MB.img) containing the FreeDOS operating system. However, if you try to boot this via PXE, you will get the following error:

Loading boot sector... booting...
This is not a bootable disk. Please insert a bootable floppy and press any key to try again...

We need to create the boot sector on this image. Important: Since we will be writing directly to the image file, make sure your floppy image is not mounted prior to the next step:

umount floppy

Copy the boot sector from the FreeDOS image (FDOEM.288 to the larger image `FAT12_16MB.img':

dd if=FDOEM.288 of=FAT12_16MB.img bs=1 count=446 seek=62 skip=62 conv=notrunc

Now you have a PXE-bootable 16MB FAT12 floppy image with FreeDOS. At this point, you can re-mount the image and copy any additional files you need.

The exact PXE configuration I'm using to boot this image is:

label bios
menu label FreeDOS
kernel memdisk
append initrd=FAT12_16MB.img

There are some other helpful step-by-step resources out there that I consulted while creating this answer.


This cannot be easily done but it’s not impossible;

You can craft a bootable FreeDOS ISO containing all your firmware upgrades Then PXE boot that ISO with PXELINUX and memdisk

 KERNEL memdisk
 APPEND iso initrd=FreDosBiosUpg.iso
  • 1
    That would get too difficult to maintain. Need to have FreeDOS have networking built-in so it can map a networked drive letter containing all the BIOS images.
    – rjt
    Nov 11, 2012 at 18:38
  • 1
    Why too difficult to maintain? You do not need networking built-in; the bios images are contained within the ISO. Just boot FreeDOS some bat with a menu and fire the right bios update; perfectly doable and not really hard to maintain.
    – Pat
    Nov 11, 2012 at 19:27
  • 1
    Rebuilding an ISO to maintain 50 or so BIOS images is nuts. Having one PXE boot of FreeDOS that reaches across the network to a share of downloaded updates would be much much easier.
    – rjt
    Nov 24, 2012 at 19:14
  • 1
    nuts?? you can build an ISO with a single line command and you call that nuts?? and 10 megs sounds too much for plain TFTP? you know what WDS/MDT/SCCM transfer ~200MB on PE boot.wim images w/o a hitch. Its seems to me you have no idea what you're talking about besides being pretty rude to the one that is giving you an answer.
    – Pat
    Nov 24, 2012 at 22:51
  • 1
    Pat, i did not mean to be rude and really do appreciate your time. Seems were having some miscommunication. The management of all the images is already out-of-hand and has become much much worse with SolidStateDrives that there is even less time than when i asked this 5 months ago. I have run mkisofs many times, but do not have the time to run fire that up, wait for it to finish, test the PXE boot and rerun it to test different BIOS images. i never said 10MB is too much for tftp, but 10MB can be too much for DOS unless it is handled just right.
    – rjt
    Nov 27, 2012 at 0:45

memdisk kernel won't be able to load bigger images,

you need to try vmlinuz kernal to load the bigger images, you can find it in the linux mirrors online.. I used one from centos to load some bigger images.

  • 1
    Most BIOS update software works with MS-DOS compatible operating systems, not Linux. vmlinuz is Linux, so it would not work.
    – rjt
    Nov 11, 2012 at 18:37
  • Although there are limits, they fall well within the parameters of the question. I've documented this in my answer.
    – Parker
    Aug 4, 2018 at 13:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .