I recently got a Compact Flash card reader and set about getting it to work under Linux (x86). I didn't find any instructions that were as straightforward as they should be, so...
First things first... here are some resources:
- USB Mass Storage Driver home page
- Using USB Mass Storage Devices (one page of the Linux USB How-To)
You should be able to follow the same procedure for other USB storage devices (portable hard drives, other media cards, etc.). With minimal modifications, the setup is the same for USB CD-ROM drives, floppies, etc.
If you have any particular successes or failures using these instructions, let me know. I originally did this on Debian sarge with Linux kernel 2.4.19. It should work with any 2.4.x series kernel. I have also done this with 2.6.x kernels and it all works.
Installing the Drivers
The USB driver serves up your reader as a SCSI device, so you also need to install the SCSI drivers. In the “SCSI Support” section, enable these. The configuration name and the module name are listed:
- SCSI Support (
CONFIG_SCSI
,scsi.o
) - SCSI disk support (
CONFIG_BLK_DEV_SD
,sd_mod.o
) - SCSI generic support (
CONFIG_CHR_DEV_SG
,sg.o
) - Probe all LUNs on each SCSI device (
CONFIG_SCSI_MULTI_LUN
), required only for multi-card devices.
You need to use the USB mass storage driver to access your reader. In the “USB Support” section of the kernel configuration, enable the following:
- Support for USB (
CONFIG_USB
,usb.o
) - Preliminary USB device file system (
CONFIG_USB_DEVICEFS
) - Whatever USB drivers you need, one or more of: ECHI HCD (
CONFIG_USB_EHCI_HCD
,usb-ehci-hcd.o
), UHCI (CONFIG_USB_UHCI
,usb-uhci.o
), OHCI (CONFIG_USB_OHCI
,usb-ohci.o
) - USB Mass Storage support (
CONFIG_USB_STORAGE
,usb-storage.o
)
Make sure you do not select the “Low Performance USB Block
Driver” (BLK_DEV_UB
). It will prevent the whole thing from working correctly.
Compile your kernel with these options and reboot (or just load the relevant modules if you've got them). And, plug the thing in, if you haven't already.
Checking it out
If you have a look through the file /proc/bus/usb/devices
, you should see a section with an S:
line and the name of your reader and an I:
line with Driver=usb-storage
. If you see that, the kernel is recognizing the USB device.
Install the sg3-utils package if you haven't already (on Debian, apt-get install sg3-utils
). To check your SCSI devices, run the command sg_scan -i
. You should see something like this:
/dev/sg0: scsi0 channel=0 id=0 lun=0 [em] type=0 eUSB Compact Flash 5.09 [wide=0 sync=0 cmdq=0 sftre=0 pq=0x0]
This indicates that the “raw” SCSI device associated with your reader is /dev/sg0
. You can also confirm that the driver is working by looking at the file /proc/scsi/scsi
.
Now, run the command sg_map
to determine the real SCSI device associated with your reader. You'll see output like this:
/dev/sg0 /dev/sda
That's it. Your card reader is /dev/sda
. The first (and almost certainly only) partition is /dev/sda1
.
Multi Card Readers
If you have an n-in-1 card reader that can deal with multiple cards, the process isn't much different. Make sure that “Probe all LUNs on each SCSI device” (CONFIG_SCSI_MULTI_LUN
) is enabled in your kernel. If this isn't compiled in, you can add this line to your /etc/modules.conf
:
options scsi_mod max_scsi_luns=8
Or, for a more temporary solution, run this command:
echo 8 > /sys/module/scsi_mod/parameters/max_luns
The device should still appear in your /proc/bus/usb/devices
as described above. When you do the sg_scan -i
, you should see several devices, like this:
/dev/sg2: scsi2 channel=0 id=0 lun=0 [em] type=0 Generic STORAGE DEVICE 0128 [wide=0 sync=0 cmdq=0 sftre=0 pq=0x0] /dev/sg3: scsi2 channel=0 id=0 lun=1 [em] type=0 Generic STORAGE DEVICE 0128 [wide=0 sync=0 cmdq=0 sftre=0 pq=0x0] /dev/sg4: scsi2 channel=0 id=0 lun=2 [em] type=0 Generic STORAGE DEVICE 0128 [wide=0 sync=0 cmdq=0 sftre=0 pq=0x0] /dev/sg5: scsi2 channel=0 id=0 lun=3 [em] type=0 Generic STORAGE DEVICE 0128 [wide=0 sync=0 cmdq=0 sftre=0 pq=0x0]
Notice that the four generics are part of the same physical device, but have different LUNs. The “Probe all LUNs on each SCSI device” option in the kernel must be enabled so it will find these.
If so, then sg_map
can do its thing:
/dev/sg2 /dev/sda /dev/sg3 /dev/sdb /dev/sg4 /dev/sdc /dev/sg5 /dev/sdd
On this system, the four slots on the card reader are mapped to SCSI devices /dev/sd[a-d]
.
If you don't have “Probe all LUNs on each SCSI device” set (as in Knoppix, Libranet, and some other default installs), you're not out of luck. You just have to manually enable the probing. You can either modify /etc/modules.conf
, or run the above command on startup.
Now, the question of which slot on the reader corresponds to which device file. I have no real advice here. Some readers give a useful description in sg_scan
. If not, put a card in and try to mount it on each one. You will get a “mount: No medium found
” for absent cards. When you find the right one, add it to your /etc/fstab
as described below and forget about it. Repeat for each kind of card you actually have.
One more note: don't cheap-out on your card reader. The first multi-card reader I bought was a off-brand and would spontaneously disconnent itself after being mounted for a minute or two. I replaced it with a SanDisk 8-in-1 and everything worked beautifully.
Thanks to Susan Macchia for her notes on getting n-in-1 card readers working that got me started with mine. Thanks also to the mailing list posted that I've long since lost that pointed out the “Probe all LUNs” thing. Thanks to Chris Bryant for the info on how to work around when “Probe all LUNs” isn't available, and Neil Gunton and Dale Thacher for even more.
Final Setup
You'll want to add a line to your /etc/fstab
so you can easily mount a card. I mount my card at /mnt/flash
; you can mount it anywhere you want, just create the mount point first. Add this line to /etc/fstab
:
/dev/sda1 /mnt/flash vfat noauto,user 0 0
The user
option lets any user mount the card. If you don't want that, remove it.
Now, you should be able to insert a card and mount it with the command mount /mnt/flash
. Before you remove the card, unmount it with the command umount /mnt/flash
.
Formatting a Card
Since cards are generally formatted as DOS ”disks”, they are formatted just like any other DOS disk. The Unix command mkfs -t vfat /dev/sda1
or mkfs -t msdos /dev/sda1
should do it.