Making a PXE-bootable 10MB or larger DOS image

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

LABEL BIOS UPG
 MENU LABEL Bios Upg
 KERNEL memdisk
 APPEND iso initrd=FreDosBiosUpg.iso