Using an external USB 3.5-inch floppy disk drive in Linux

Back in 2004 I needed to get some files off my old 3.5″ floppy disks, so I bought an external USB floppy disk drive to use with a laptop running Windows XP. The label on the drive gives the manufacturer and model as ‘SmartDisk: FDUSB-TM2, Mitsumi Model #: D353FUE’.

Anyway, today I wanted to throw out some 720KB DD (Double Density) and 1440KB HD (High Density) 3.5″ floppy disks but first needed to check their contents and wipe them. So I dug out the SmartDisk USB drive to see if it would work with the current Gentoo Linux installation on my newest laptop. I was pleased to discover that it does, and below are some notes on how to use it in case anyone else needs to use one of these devices.

Once plugged in to a USB port on my laptop, the lsusb command shows the device has been recognised:

Bus 001 Device 013: ID 03ee:6901 Mitsumi SmartDisk FDD

Note that the Linux floppy driver is not needed for USB floppy disk drives:

root # grep -i CONFIG_BLK_DEV_FD /usr/src/linux/.config
# CONFIG_BLK_DEV_FD is not set

A Linux utility named ufiformat is used to low-level format floppy disks in USB floppy disk drives. A Gentoo Linux ebuild for Version 0.9.9 of ufiformat is listed below, and it can be used in a local overlay under the category sys-fs:

# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: $

EAPI=5

DESCRIPTION="USB Floppy Disk formatting tool"
HOMEPAGE="http://www.geocities.jp/tedi_world/format_usbfdd_e.html"
SRC_URI="http://www.geocities.jp/tedi_world/${P}.tar.gz"

LICENSE="GPL-2"
SLOT="0"
KEYWORDS="~amd64 ~x86"
IUSE=""

RDEPEND="sys-fs/e2fsprogs"
DEPEND=${RDEPEND}

UPDATE (2 November 2019): As of March 31, 2019, Yahoo! Geocities service has been discontinued, so the ufiformat repository has been moved to GitHub. I have updated the link in the paragraph above accordingly. Therefore, in the ebuild the HOMEPAGE and SRC_URI variables need to be changed – see the update at the end of this blog post.

The ufiformat utility is straightforward to use:

root # ufiformat --help
Usage: ufiformat [OPTION]... [DEVICE]
Format a floppy disk in a USB floppy disk DEVICE.

  -f, --format [SIZE]  specify format capacity SIZE in KB
                       without -f option, the format of the current media will be used
  -V, --verify         verify the medium after formatting
  -F, --force          do not perform any safety checks
  -i, --inquire        show device information, instead of performing format
                       without DEVICE argument, list USB floppy disk devices
  -v, --verbose        show detailed output
  -q, --quiet          suppress minor output
  -h, --help           show this message

To find the device name, use the blkid command before plugging in the USB cable and again after plugging in the USB cable. The extra device listed the second time will be the floppy disk drive. For example, in my case the new line at the end of the blkid output indicated the drive was /dev/sdd:

/dev/sdd: SEC_TYPE="msdos" UUID="BBBA-37AF" TYPE="vfat"

The fdisk command will confirm that the device is the floppy drive:

root # fdisk -l /dev/sdd
Disk /dev/sdd: 720 KiB, 737280 bytes, 1440 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: 0x00000000

Note that /dev/sdd will not be listed in the output of blkid if there is no disk in the floppy drive, although the ls command will list /dev/sdd while the drive is connected to the computer.

Notice that there are no devices /dev/fd0, /dev/fd1, /dev/fd2 and /dev/fd3, etc. This does not matter.

root # ls /dev
audio1           dri      i2c-10   kmem          mapper              nvidiactl  sda1       sequencer2  tty0   tty2   tty30  tty41  tty52  tty63    usbmon3     vcs2    vcsa12
autofs           dsp1     i2c-11   kmsg          mcelog              nvram      sda2       sg0         tty1   tty20  tty31  tty42  tty53  tty7     usbmon4     vcs3    vcsa2
block            fb0      i2c-2    log           mem                 pktcdvd    sda3       sg1         tty10  tty21  tty32  tty43  tty54  tty8     v4l         vcs4    vcsa3
bsg              fd       i2c-3    loop-control  memory_bandwidth    port       sda5       sg2         tty11  tty22  tty33  tty44  tty55  tty9     vboxdrv     vcs5    vcsa4
bus              full     i2c-4    loop0         mixer               ptmx       sda6       sg3         tty12  tty23  tty34  tty45  tty56  ttyS0    vboxdrvu    vcs6    vcsa5
char             fuse     i2c-5    loop1         mixer1              pts        sda7       shm         tty13  tty24  tty35  tty46  tty57  ttyS1    vboxnetctl  vcs7    vcsa6
console          hidraw0  i2c-6    loop2         mqueue              random     sdb        snapshot    tty14  tty25  tty36  tty47  tty58  ttyS2    vboxusb     vcs8    vcsa7
core             hidraw1  i2c-7    loop3         network_latency     rfkill     sdb1       snd         tty15  tty26  tty37  tty48  tty59  ttyS3    vcs         vcs9    vcsa8
cpu              hidraw2  i2c-8    loop4         network_throughput  root       sdc        stderr      tty16  tty27  tty38  tty49  tty6   urandom  vcs1        vcsa    vcsa9
cpu_dma_latency  hpet     i2c-9    loop5         null                rtc        sdc1       stdin       tty17  tty28  tty39  tty5   tty60  usbmon0  vcs10       vcsa1   vga_arbiter
cuse             i2c-0    initctl  loop6         nvidia-modeset      rtc0       sdd        stdout      tty18  tty29  tty4   tty50  tty61  usbmon1  vcs11       vcsa10  video0
disk             i2c-1    input    loop7         nvidia0             sda        sequencer  tty         tty19  tty3   tty40  tty51  tty62  usbmon2  vcs12       vcsa11  zero
root # ls -la /dev/fd
lrwxrwxrwx 1 root root 13 Jan 17 02:13 /dev/fd -> /proc/self/fd
root # ls -la /proc/self/fd
total 0
dr-x------ 2 root root  0 Jan 17 04:26 .
dr-xr-xr-x 8 root root  0 Jan 17 04:26 ..
lrwx------ 1 root root 64 Jan 17 04:26 0 -> /dev/pts/1
lrwx------ 1 root root 64 Jan 17 04:26 1 -> /dev/pts/1
lrwx------ 1 root root 64 Jan 17 04:26 2 -> /dev/pts/1
lr-x------ 1 root root 64 Jan 17 04:26 3 -> /proc/17669/fd

To format an HD floppy disk with the FAT file system, I did the following:

root # ufiformat -f 1440 /dev/sdd
geometry: track=80, head=2, sector=18, block=512
done                                   
root # /usr/sbin/mkfs.vfat /dev/sdd
mkfs.fat 4.0 (2016-05-06)
attribute "partition" not found
root # ufiformat -i /dev/sdd
vendor:  MITSUMI
product: USB FDD
write protect: off
media type: 2HD
status      block size   kb
formatted    2880  512 1440
formattable  2880  512 1440
formattable  1232 1024 1232
formattable  2400  512 1200

To format a DD floppy disk with the FAT file system, I did the following:

root # ufiformat -f 720 /dev/sdd
geometry: track=80, head=2, sector=9, block=512
done                                   
root # /usr/sbin/mkfs.vfat /dev/sdd
mkfs.fat 4.0 (2016-05-06)
attribute "partition" not found
root # ufiformat -i /dev/sdd
vendor:  MITSUMI
product: USB FDD
write protect: off
media type: 2DD
status      block size   kb
formatted    1440  512  720
formattable  1440  512  720

I use the KDE Desktop Environment. The Device Notifier widget in the System Tray shows the drive and — once a formatted floppy disk is in the drive — it is possible to use the Device Notifier to mount, open and unmount the floppy disk. However, it is also possible to use the command line:

root # mkdir /mnt/floppy
root # mount /dev/sdd /mnt/floppy
root # ls /mnt/floppy
root # cp /test.txt /mnt/floppy/
root # ls /mnt/floppy
test.txt
root # umount /dev/sdd

Earlier in this post I showed examples of formatting floppy disks using the FAT file system, but it is of course possible to format them using other file systems, such as:

root # mkfs.ext2 /dev/sdd
mke2fs 1.43.3 (04-Sep-2016)
/dev/sdd contains a vfat file system
Proceed anyway? (y,n) y
Creating filesystem with 720 1k blocks and 96 inodes

Allocating group tables: done                            
Writing inode tables: done                            
Writing superblocks and filesystem accounting information: done

Anyway, I was able to check the contents of the floppies and wipe them before disposing of them. It’s good to know that some old technologies can still be used when needs be. I won’t be throwing out the old floppy disk drive just yet.

UPDATE (2 November 2019): As of March 31, 2019, Yahoo! Geocities service has been discontinued, so the ufiformat repository has been moved to GitHub. Therefore, in the ebuild the HOMEPAGE and SRC_URI variables need to be changed from:

HOMEPAGE="http://www.geocities.jp/tedi_world/format_usbfdd_e.html"
SRC_URI="http://www.geocities.jp/tedi_world/${P}.tar.gz"

to:

HOMEPAGE="https://github.com/tedigh/ufiformat/"
SRC_URI="https://github.com/tedigh/ufiformat/archive/v0.9.9.zip"

or:

HOMEPAGE="https://github.com/tedigh/ufiformat/"
SRC_URI="https://github.com/tedigh/ufiformat/archive/v{$PV}.zip"