Debian GNU/Linux and the Canon PowerShot A40


These are some notes on how I persuaded Debian GNU/Linux to talk to my very fine Canon PowerShot A40 digital camera, which interfaces only via the USB port. There should be something useful here for users of other GNU/Linux distributions, but for this installation I am using Debian Woody on my Toshiba Portégé 3110CT laptop.

New! I've put up a short list of FAQs. Please feel free to add to them. I've also added a section on using an Omniflash USB Compact Flash card reader, and a page on converting the A40's movies into compressed MPEGs.

Feel free to contact me if you have any questions or comments. Any feedback is welcome, and I will do my best to help you out if you need it. However, please be aware that I am very far from being an expert.

Ben Edgington,
27 June 2002
Revised 30 July 2002
Revised 2 January 2003

Home


Index

This page

Other pages


Introduction

Equipment manufacturers are sadly reluctant to support Linux: Canon are no exception. I still have no Linux drivers for my CanoScan N670U, and they don't provide any Linux drivers with the PowerShot A40.

Respect, therefore, goes to the members of the gphoto project who have filled the breach with drivers for a whole range of digital cameras, including the A40. Installing it on my system was something of a saga, but it should become easier with future Linux distributions. Here's my step by step guide.


Kernel preparation

Note: In the following I sometimes refer to kernel parameters, modules and recompiling. Don't Panic! This is because I run a custom kernel, and have stripped out a lot of the stuff I didn't use. If you are using the stock kernel that came with a distribution then it is likely that all of the parameters are already set and modules compiled. Just give it a try and see what happens. If you have trouble check your kernel's .config file for the parameters that I mention, and only then do you need to consider recompiling.

I gather that sufficient USB support is included in kernels 2.2.18 and above. In any case, I am using 2.4.17, and what follows assumes that the kernel is modularised (KMOD is set).

You can check whether your kernel is sufficiently USB enabled like this, for example. As root, doing the following should create a directory /proc/bus/usb. (NB this is correct for my hardware. It's possible you might need one of the other USB drivers loaded. Try usb-ohci, perhaps, or RTFM in that case.)

# modprobe usb-uhci

Make sure you are not in the /proc/bus/usb directory and try mounting the USB filesystem. Some files should now appear in that directory,

# mount -t usbdevfs none /proc/bus/usb
# ls -l /proc/bus/usb
total 0
dr-xr-xr-x    1 root     root            0 Jun 25 14:15 001
-r--r--r--    1 root     root            0 Jun 25 14:15 devices
-r--r--r--    1 root     root            0 Jun 25 14:15 drivers

If this all works then you can skip this section 8^).

If not, you may need to enable USB in the kernel (I chose to compile it as a module), and select modules uhci.o and usb-uhci.o. The /proc/bus/usb filesystem also needs to be enabled, so make sure that is selected in the USB section.

To use the "hotplug" functionality detailed below you need also to enable hotplugging in the General Settings section of the kernel configuration.

For user-space USB access you need to install the usblib package, and later on we will need the usblib-dev package, so install that as well.

Now check the installation after booting the new kernel as described above.

Summary

Check that at least the following kernel configuration options are set. If not you need to recompile.

In general setup:

CONFIG_HOTPLUG=y

In USB support:

CONFIG_USB=m
CONFIG_USB_DEVICEFS=y
CONFIG_USB_UHCI=m
CONFIG_USB_UHCI_ALT=m

Install the usblib and usblib-dev packages.


Building gphoto2

Unfortunately the version of gphoto2 in the Debian "stable" archive at the time of installation (version 2.0final-4) did not include support for the PowerShot A40, so I had to build it from source, recent versions of which do contain support for the A40 (and A30).

Note that gphoto2 version 2.1.0, which supports the A40, has now made it into the Debian "testing/sarge" archive. You can either upgrade your whole distribution to this version, or do what I do and run a mixture of "stable/woody" and "testing/sarge". But the latter is complicated and I do not really recommend it. If you do install the "testing" version of gphoto2 on "stable", you will need at least libreadline4 and libusb-0.1-4 from "testing" as well.

Check whether your version is up to date by doing

$ gphoto2 --list-cameras | grep A40
        "Canon PowerShot A40"

If the PowerShot A40 is listed then there is no need to rebuild gphoto2. Otherwise follow the steps below, or download a newer binary package for your Linux distribution. Some sources for these are listed in the FAQ.

If you need to build from the source code, first install the usblib package (called libusb-0.1-4 in this case) and the usblib-dev package so that the gphoto2 build can find the usb stuff it needs. I also needed to install the gettext package, although this is apparently now optional, and the pkg-config package. You may also wish to install the libexif and libexif-dev packages so that you can view the meta-data that gphoto2 stores alongside your images.

Revised: 2 January 2003 The latest official release of the gphoto2 source code is version 2.1.1 (1 December 2002). I recommend using this rather than the CVS code: it's a little more straightforward.

To get the source, follow the "Download" link from the Gphoto website. Make sure you download both libgphoto2-2.1.1 and gphoto2-2.1.1 which is the command-line front end to the library. This version of gphoto2 is the first in which the library and the command-line interface have been split into separate packages.

The INSTALL file in each of the packages contains good instructions on compiling and installing. But note that you may have to give pkg-config a little help to find the meta-data for the new libgphoto2: export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig

Check the summary printed by configure to make sure that it has correctly configured for USB. It took me a while to realise that I needed to install libusb-dev 8^)

Summary

Troubleshooting

If when you try to run gphoto2 you get a message that says something like this,

error while loading shared libraries: libgphoto2.so.2:
cannot open shared object file: No such file or directory

then the following might help.

The source compilation will probably put the shared libraries for gphoto2 in the /usr/local filesystem. This is little used on Debian, and it is possible that your system is not set up to look there. The fix is to add a line to the /etc/ld.so.conf file reading "/usr/local/lib" (without the quotes) and then to run the ldconfig program as root.

You can check where the operating system is looking for libraries when the gphoto2 program is run by executing ldd /usr/local/bin/gphoto2.


Using gphoto2 without hotplug

The most convenient and safe method of accessing the camera is by means of the hotplug package described below. It is, however, possible to access the camera without hotplug but with some manual intervention.

Assuming that your USB subsystem is running correctly and that your gphoto2 installation supports the A40 then the following steps should allow you to access the camera as the root user. This is not recommended! But it may be OK on single-user systems.

Do these as root,

# modprobe usb-uhci
# mount -t usbdevfs none /proc/bus/usb

Now connect and switch on the camera in play-back mode (mode-wheel to >), and still as root check if you can see its contents:

# gphoto2 -L

It is also possible to allow gphoto2 to be run as a normal user. First locate the correct device in /proc/bus/usb/001/ (at least that's where it is on my machine - you may need to hunt around). The device representing the camera is one of the files in this directory, eg. file 004. To allow user foo to access the camera do something like,

# chown foo 004

Now try running gphoto2 as the ordinary user.

Note: If the camera is correctly auto-detected, but listing the contents fails, then it probably means that the permissions are wrong on the USB device (you do not have write-permission). Double-check the above steps.


Using hotplug

The best way of allowing users access to the USB port appears to be with the hotplug package, so install that (for non-Debian users, it should be available somewhere at linux-hotplug.sourceforge.net. That site has much more information about setting-up hotplugging). The alternative is to access USB as root, which is not recommended, or to manually set the permissions of the USB device for a specific user every time you want to use it (described above). The hotplug package does useful stuff like automatic recognition of the USB device, and mounting of /proc/bus/usb etc.

In the /etc/hotplug/ directory the following commands setup the hotplug scripts to recognise the camera (this is probably a Debian-specific method - other distributions may use the usb.usermap file directly).

# /usr/local/lib/libgphoto2/print-usb-usermap > usb.usermap.local
# update-usb.usermap

[Notes:

Endnotes.]

Now we need to tell it how to set the permissions on the USB port. I modified the usbcam.user file which comes with the gphoto2 source code distribution.

# mkdir usb
# cd usb
# cp ~/gphoto2/packaging/linux-hotplug/usbcam.user ./usbcam
# chmod a+x usbcam

Edit the script to set the USB user to your login ID. This enables you, and only you, to use the device. For more complex set-ups have a look at the gphoto2/doc/gphoto2.txt file.

Before plugging in the camera do a tail -f /var/log/messages to see some reassuring (or if not, diagnostic) information about what the machine can see on the USB port.

Now connect the camera, switch it on in playback mode (mode-wheel to >), check the syslog messages, and all being well see if the camera is auti-detected by gphoto2:

ben@foxglove:ben$ gphoto2 --auto-detect
Model                          Port                                             
----------------------------------------------------------
Canon PowerShot A40            usb:            

ben@foxglove:ben$ gphoto2 -L
Detected a 'Canon PowerShot A40'.
There are no files in folder '/'.
There are no files in folder '/DCIM'.
There are 3 files in folder '/DCIM/100CANON':
#1     MVI_0096.AVI               rd  1751 KB video/x-msvideo
#2     MVI_0099.AVI               rd  1082 KB video/x-msvideo
<etc...>

Whehey! Now read the gphoto2 man page and go and play 8^) Everything I tried seems to work fine, including image, movie and thumbnail download. Good luck!

Note: If the camera is correctly auto-detected, but listing the contents fails, then it probably means that the permissions are wrong on the USB device (you do not have write-permission). Check your hotplug set-up.


Setting up the OmniFlash Compact Flash reader

Another option for downloading the pictures to your PC is to use a card-reading device. I've acquired the excellent OmniFlash UnoCF Compact Flash reader.

It wasn't too hard to set up under Linux, but I found I needed to enable some kernel options on my custom kernel: CONFIG_SCSI=m, CONFIG_BLK_DEV_SD=m, CONFIG_SD_EXTRA_DEVS=40, and CONFIG_USB_STORAGE=m. These provide the various modules needed (scsi_mod.o, sd_mod.o and usb-storage.o).

Now when the UnoCF device is connected to the USB port the kernel recognises it and loads-up the appropriate modules. You can check that all is well as follows,

foxglove:~# cat /proc/scsi/scsi
Attached devices: 
Host: scsi0 Channel: 00 Id: 00 Lun: 00
  Vendor: OEI-USB  Model: CompactFlash     Rev: 1.03
  Type:   Direct-Access                    ANSI SCSI revision: 02

This is the first (and only) device on /proc/scsi/scsi so the device /dev/sda1 needs to be mounted to read it. If it were the second device then you'd need to mount /dev/sdb1, etc. The "1" refers to its one and only partition.

You can mount it, as root, after making a mount point, with

# mkdir /mnt/uno
# mount -t vfat /dev/sda1 /mnt/uno

This gives a bunch of SCSI error messages in /var/log/messages, but nothing seems to break.

A better solution, however, is to make use of the hotplug facility described above.

We want the device mounted for an ordinary user, ie. me (uid=1000), and to allow me to unmount it before I unplug it (very important!). So we need an entry in /etc/fstab

/dev/sda1       /mnt/uno        vfat    users,noauto    0       0

Now make an executable script /etc/hotplug/usb/usb-storage that will mount the directory when the device is attached. This is called automatically by the hotplug scripts when the device is attached. Here's what I did; it's not very sophisticated 8^),

#!/bin/bash
#
# /etc/hotplug/usb/usb-storage
#
# Sets up newly plugged in USB mass storage so that just one certain user
# can access it
USER_UID=1000
USER_GID=1000
#
mount /mnt/uno -o uid=${USER_UID},gid=${USER_GID}

Now when the UnoCF device is plugged in we can just use the /mnt/uno directory as a normal filesystem. I've read some comments that it must be unmounted before disconnecting the UnoCF device, or else data may be corrupted. I don't know the truth of that, but it would seem like a wise precaution: umount /mnt/uno