Ubuntu Create Floppy Image

Floppy

 * Very useful for bios flashing via PXE booting or USB booting

A simple floppy (or Superfloppy) image has no MBR and the volume starts at the start of the disk. USB sticks can be formatted this way ( as a Superfloppy). (I think this was the default in the early days, but can cause problems, see later)

Floppy images are usually 1.4 or 2.88 Mb but you can generate them larger - however after about 16Mb you start running into compatibility problems.

ms-sys create boot sector
you will need to download ms-sys and build it;

tar zxvf ms-sys-2.2.1.tar.gz cd ms-sys-2.2.1 make

Creating
A standard 1.44 floppy disk is 2 heads, 80 cylinders(tracks) and 18 sectors /track - with 512bytes / sector.

2x80x18x512=1474560 bytes dd if=/dev/zero of=/tmp/test.ima bs=512 count=2880

To make one 6 times bigger = ~8.8Mb

6x(2x80x18) = 17280 sectors (17280x512=8847360 bytes)

$ dd if=/dev/zero of=/tmp/test.ima bs=512 count=17280 17280+0 records in 17280+0 records out 8847360 bytes (8.8 MB) copied, 0.0519053 s, 170 MB/s

=DOS Bootable Floppy=

After creating the empty image with fdisk

Format image
Format floppy the standard FAT12 $ mkfs.msdos -F 12 -n "richud.com" /tmp/test.ima mkfs.msdos 3.0.9 (31 Jan 2010)

Write boot sector
Write a FAT12 boot sector (FAT12 floppy boot record) to device using ms-sys $ ./ms-sys-2.2.1/bin/ms-sys -f -1 /tmp/test.ima FAT12 boot record successfully written to /tmp/test.ima

Fix the boot record
Note, Unlike a hard drive image, you aren't changing any of the geometry. This means 18h and 1Ah aren't changed from a normal floppy size and need putting back to original values in this size disk. In this example we are using (C/H/S) 80/16/18 and starting sector is 0 (as there is no MBR.) i.e. the value of 1A wants putting back from 16 to 2, and definitely not 64 (40h) as mkfs.msdos decided it was rather than 16. (If you were creating a normal sized floppy (1.44Mb), none of these would need changing as they should be right to begin with.)

hexedit /tmp/test.ima


 * offset 15 Media Descriptor = F0 (1.44Mb floppy drive)
 * offset 18 Sectors/track (18) = 12 (back to a floppy default)
 * offset 1A Heads (02) = 02 (back to floppy default)
 * offset 1C-1D Hidden Sectors in Partition (0) = 00 (should already be 0)
 * offset 24 Logical Drive Number of Partition = 00 (should already be 0)

Original 00000000  EB 3C 90 4D  53 57 49 4E  34 2E 31 00  02 08 08 00  02 00 02 80  43 F8 08 00  .<.MSWIN4.1.........C... 00000018  20 00 40 00  00 00 00 00  00 00 00 00  00 00 29 6A  B2 B0 55 72  69 63 68 75   .@...........)j..Urichu 00000030   64 2E 63 6F  6D 20 46 41  54 31 32 20  20 20 33 C9  8E D1 BC FC  7B 16 07 BD  d.com FAT12   3.....{...

Corrected 00000000  EB 3C 90 4D  53 57 49 4E  34 2E 31 00  02 08 08 00  02 00 02 80  43 F0 08 00  .<.MSWIN4.1.........C... 00000018  12 00 02 00  00 00 00 00  00 00 00 00  00 00 29 FC  48 B3 79 72  69 63 68 75  ..............).H.yrichu 00000030   64 2E 63 6F  6D 20 46 41  54 31 32 20  20 20 33 C9  8E D1 BC FC  7B 16 07 BD  d.com FAT12   3.....{...

Mounting
Mount the floppy image on the loopback block device /dev/loop0

losetup /dev/loop0 /tmp/test.ima

If you have automount on then it may pop up in Nautilus otherwise do

udisks --mount /dev/loop0

Copy files
Using Win98SE boot files

Copy
 * io.sys
 * msdos.sys
 * command.com

Unmounting
udisks --unmount /dev/loop0

losetup -d /dev/loop0

Test
Unlike a harddisk image this works fine with qemu. Note, if you dont specify -fda it will assume its a hdd image and not boot.


 * Update, 'qemu' now is 'qemu-system-i386' in Ubuntu >= 12.10

$ qemu -fda /tmp/test.ima



=FreeDOS=

Same applies, with a two alterations
 * FAT 16 instead of FAT 12 with mkfs (as ms-sys only does FAT16/32 boot sectors for FreeDOS), FAT16 needs minimum size ~8.8Mb (bs=512 count=17280).
 * ms-sys option -5, "Write a FAT16 partition FreeDOS boot record to device"

$ mkfs.msdos -F 16 -n "richud.com" /tmp/test.ima $ ./ms-sys-2.2.1/bin/ms-sys -f -5 /tmp/test.ima

Same mods to the boot sector to correct it, Offset 15h, 18h and 1Ah

When mounted you only need these two boot files. FreeDOS kernel.sys and FreeCOM command.com available here. Suggest getting build 2040 fat32 kernel, ke386f32.zip
 * kernel.sys
 * command.com




 * Note, A 16Mb floppy seemed to work ok in the real world, but failed on Qemu just saying 'FreeDOS'...and not loading the kernel.

=Syslinux=

Same applies as above, create empty disk image with fdisk (1.44Mb will need FAT12, larger FAT16) $ mkfs.msdos -F 16 -n "richud.com" /tmp/test.ima $ syslinux --install /tmp/test.ima
 * Format it FAT16
 * Put syslinux boot sector in it

You should see you now have ldlinux.sys too, e.g. /media/richud.com/ldlinux.sys

Same mods to the boot sector to correct it, Offset 15h, 18h and 1Ah

Mount image $ losetup /dev/loop0 /tmp/test.ima && sleep 1 && udisks --mount /dev/loop0 Mounted /org/freedesktop/UDisks/devices/loop0 at /media/richud.com

Create a syslinux.cfg and save to root, this is the most basic possible to boot a linux kernel and initial ramdisk DEFAULT Linux LABEL Linux KERNEL /bzImage INITRD /initramfs.cp.lzma

Assuming they were small enough to fit on the disk copy bzImage and initramfs.cp.lzma to it.

Unmount udisks --unmount /dev/loop0 && losetup -d /dev/loop0

Note, if you are tempted to make say a 20Mb floppy and copy kernel/initrd (probably the size you'd need to make them fit), the only thing I could get it to work with was qemu specifying -hda (not -fda, which unsurprisingly craps out. Using the floppy frig in virtualbox also craps out in same way as qemu -fda with CHS Read Sector Errors.)

=Problem Solving= Qemu has issues with large floppies, if any files reside outside the first part of the image (perhaps after 2.88Mb?) you will run into I/O problems. It is however useful to make sure the boot sector fix is correct, and should boot correctly assuming you just copy the bare minimum core boot files to it.

e.g. FreeDOS It will either fail to boot at all (if kernel.sys is outside) or things in the image wont work. e.g. Error reading from drive A: DOS area: unknown command given to driver (A)bort, (I)gnore, (R)etry, (F)ail?