C Program to Generate a Blank MS-DOS Floppy Image in Linux

How do you do, fellow old-timers? Today’s post is going to be a bit of a crossover, because I’m going to get into some programming stuff, some Linux stuff, and some DOS stuff all at the same time. I’m going to show you a program that I wrote a while back that uses POSIX API functions to create a blank formatted floppy disk image for VirtualBox VMs running MS-DOS

Of course you can always use Linux’s mkfs.msdos command to do this, but I wanted a cross-platform solution that would work on any POSIX system (keep in mind I was using MacOS at the time). So I wrote my own version of mkfs.msdos that I call mkfloppy.

The floppy generator I have written actually consists of two parts: The first part – mkfloppy – creates a blank file where all bytes are zero. The second part – dosformat – formats this file as a floppy disk image by writing all the FAT filesystem metadata to it. This is information that I copied directly from an existing blank floppy image into a raw binary data file, which is to be read from and then copied onto the first 512 bytes of the new floppy image by dosformat.

The code for mkfloppy is as follows:

 1 #include <stdlib.h>
 2 #include <unistd.h>
 3 #include <errno.h>
 4 #include <string.h>
 5 #include <sys/wait.h>
 7 #define waitforchild()\
 8 int statloc;\
 9 wait( &statloc );\
10 if( statloc != 0 ) return statloc
12 int mainint argc, char **argv ){
13         pid_t pid;
14         // Build dd command:
15         char cmd[255];
16         strcpy( cmd, "dd if=/dev/zero of=" );
17         strcat( cmd, argv[1] );
18         strcat( cmd, " bs=1024 count=1440" );
19         // First fork-exec is for dd
20         if( (pid = fork()) < 0 ){
21                 write2"Fork error!\n"12 );
22                 return errno;
23         }
24         else if( pid == 0 ){
25                 system( cmd );
26         }
27         else{
28                 waitforchild();
29         }
30         // Second fork-exec is for dosformat
31         if( (pid = fork()) < 0 ){
32                 write2"Fork error!\n"12 );
33                 return errno;
34         }
35         else if( pid == 0 ){
36                 execl"/usr/local/bin/dosformat""dosformat", argv[1], (char *) 0 );
37         }
38         else{
39                 waitforchild();
40         }
41         return 0;
42 }

This program is fairly easy to understand. All it is is a frontend for dd that executes the following command:

$ dd if=/dev/zero of=arg bs=1024 count=1440

It then forks into the dosformat program, which has the following code:

 1 // This module formats a floppy image with an MS-DOS
 2 // FAT filesystem.
 4 #include <unistd.h>
 5 #include <fcntl.h>
 7 int mainint argc, char **argv ){
 8         int in = open( "/usr/local/bin/format.bin"O_RDONLY );
 9         int out = open( argv[1], O_RDWR );
10         char c;
11         forint i = 0; i < 512; i++ ){
12         // Copy binary data from format table
13                 read( in, &c, 1 );
14                 write( out, &c, 1 );
15         }
16         close( in );
17         char str[4];
18         str[0] = 0xf0; str[1] = str[2] = 0xff; str[3] = '\0';
19         write( out, str, 3 );
20         lseek( out, 0x1400SEEK_SET );
21         write( out, str, 3 );
22         lseek( out, 0x4200SEEK_SET );
23         c = 0xf6;
24         whilelseek( out, 0SEEK_CUR ) != 1024 * 1440 ){
25                 write( out, &c, 1 );
26         }
27         close( out );
28         return 0;
29 }

This program reads bytes one-by-one from the data file format.bin, which is basically just a binary copy of the FAT filesystem’s boot record, and then it writes that data to the new floppy image. It then makes a few other changes later on in the file based on byte patterns that I observed while taking a hexdump of the existing floppy image.

You can download a copy of format.bin here. I had to change the extension to .doc so that WordPress would let me upload it, so you’ll need to change it back to .bin if you want to use it. (No, it’s not a virus, I promise. You can view the file in hexdump if you don’t believe me. 🙂 )

To run this program, you would compile both mkfloppy and dosformat to executable files with those same names, get the format.bin file and copy all three files to /usr/local/bin, then enter the following command:

$ mkfloppy target.img

After I’ve generated the blank floppy image, I can then use a hack to create a floppy image for a directory without having to use a paid program like WinImage or MagicISO. Basically, this hack involves installing an optical media driver in my DOS VM if I haven’t already, then using any open source ISO generator program to create an ISO file from the target folder, then inserting the ISO file into the virtual optical drive of the VM and the blank floppy image into the virtual floppy drive, then going into the DOS VM and using xcopy /s to copy the contents of the D: drive to the A: drive.

Yeah, basically there are no open source programs for creating floppy images from directories, but the fact that there are equivalent programs for ISO’s means you can use this little loophole. Some people may find it easier to just pay to install a proprietary floppy image generator, but I’m a cheapskate who goes out of his way to avoid paying for things, so that’s why I employ hacks like this.

So there you have it, my entire cross-platform system for creating DOS floppy images from directories without paying for any additional software. Hope you enjoyed this post. See you next time.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s