Tuesday, April 30, 2019

USB Flash Media on Linux

USB flash media is one of the most useful devices to come along in recent computer history.  Gone are the days of floppy diskettes, CD-R media, and DVD-R media.  While those were fine, USB flash media has just made things much easier.  Our best interim solution in the 90s was the Iomega Zip drive (full disclosure: one still sits on my desk and I use it for sneaker-netting to vintage systems that have SCSI and a Zip drive).

OK, so there are some things to know when using USB flash media on Linux.  For me, the two common things I do are boot ISO images and copy files between systems.  Usually old Windows systems that I use for programming old two-way radio systems.

In the case of booting ISO images, you just need to dd the file to the block device.  Let's say I insert flash media and see in dmesg that it's /dev/sdc.  I would write out the ISO image using this command:

dd if=FUN_OPERATING_SYSTEM.iso of=/dev/sdc status=progress oflag=sync bs=4096

You may need to use the mkhybrid command on some Linux ISO images to make sure it loads from USB media.  Do that on the ISO file before running dd.  So what do the options do?
  • if is the "input file".  This is what I want to write to USB.
  • of is the "output file".  Where is it going?  In this case, a block device called /dev/sdc.
  • status=progress is a GNU feature that shows some status information during the transfer.
  • oflag=sync means "really write it to the block device".
  • bs=4096 means write 4k at a time.  By default, dd will just do one byte at a time.  For an 8GB ISO, that can take a while.  I have successfully set a 32k block size and dd performs just fine, so I do bs=32768
Great, now you can write out an ISO.  How about file transfer?  In my case, I stick with the FAT32 filesystem.  Even non-DOS operating systems can read and write it.  First, you need to partition the USB device and create a single partition as partition 1.  Alternatively you can format the device on Windows and it will do all of that for you.  Create a FAT32 filesystem on the first partition of the device with a command like:

mkfs.dos -F 32 /dev/sde1

Now mount it:

mount -o flush /dev/sde1 /mnt

What is "-o flush"?  This tells the kernel to sync data to the device when it's idle.  Other filesystems tend to call this "-o sync", but the distinction usually for FAT32 is that it will simply sync data earlier.  Usually the "sync" option for the filesystem means sync during the write which can cause it to take a long time to write.

The "-o flush" option also means when you unmount the device it will most likely be ready to remove.  This is also way faster than running sync before unmounting.  I've also heard urban legends of the sync command destroying the life of USB flash media, so I guess there's that.

If you have ever waited a long time to dd something to a USB flash device, try some of the above options for dd and mounting.  It makes the devices much nicer to work with on Linux.

No comments: