Welcome to the Yargy Bot Familiar Backup Howto!

Familiar Linux is a distribution of the famous operating system designed to run on HP/Compaq iPAQ handheld computers.

This Howto describes how to create a copy of your Familiar Linux root filesystem as a JFFS2 image file. It then goes on to describe how to use this image file to create a minimally-sized and cleaned-up JFFS2 image that is more suitable for re-flashing. At the time of writing, I'm running Familiar 0.7 with a version 2.4.19-rmk6-pxa1-hh23 kernel on my iPAQ 3870, and Debian Sid with a custom version 2.4.20 kernel on my desktop machine.

Creating a copy of your iPAQ's flash memory root partition (which contains the root filesystem) is pretty straight-forward. You will need to execute the commands below as the root user.
Some people have reported doing this successfully by reading from the /dev/mtdblock/1 device, but I and others have had some trouble with this, so I prefer to load the mtdchar module with this command
# modprobe mtdchar
and then read from the /dev/mtd/1ro device with a command like this
# dd if=/dev/mtd/1ro of=/path/to/imagefile.jffs2
where "/path/to/imagefile.jffs2" is where you want to save the JFFS2 image file. This will need to be on a different filesystem, as the root filesytem cannot contain a complete, uncompressed copy of itself. Personally, I usually create the image file on a filesystem NFS mounted from my desktop so that I don't need to separately copy the file to my desktop machine for the operation described below.

The image file created by the above command is just a direct copy of everything in the root partition of the iPAQ's flash memory. This is not suitable for re-flashing to the iPAQ later, so it isn't actually much use as a backup. The reasons that it's no good for re-flashing are two-fold.

  • As at bootloader version 2.20.4, files larger than about 22MB cannot be used by the "load root" command. The root partition fills almost all of the iPAQ's 32MB of flash memory (on my 3870 - other models have more or less flash memory).
  • The JFFS2 filesystem is a journalling filesystem, so there is journal information and so on that you don't really want in a freshly-flashed filesystem.
Fortunately, it's not too difficult to create a minimally-sized and cleaned-up version of the filesystem in a new image file.

You need some non-standard kernel bits on your desktop (or laptop or whatever) for this, so if you're not into re-compiling your kernel, this is probably not for you. I think these bits can all be compiled as modules, so a "complete"  kernel rebuild may not be required (ie. you might be able to get away with just building the modules).

First, you need loopback device support. This is fairly common in "standard" kernels. Try step 2 below. If it works, you have loopback device support already. If you use menuconfig or xconfig to configure your kernel, you'll find the loopback device option under "Block devices".

Next, you need Memory Technology Device (MTD) support. This is rarely used in desktop machines. MTD support has it's own section in menuconfig/xconfig. You need to have "Memory Technology Device (MTD) support" (obviously), "Caching block device access to MTD devices" (mtdblock module), and "MTD emulation using block device" (blkmtd), which is under "Self-contained MTD device drivers". This last one MUST be compiled as a module because you need to pass parameters to it later.
You also need mkfs.jffs2 installed. Under Debian, this is in a package called mtd-tools.

1. Load up the kernel modules you need, if necessary. Some or all of these might load automatically as you go along.
# modprobe loop
# modprobe mtdblock

2. Set up a loopback device on your existing jffs2 file. You might want to make a backup of the jffs2 file beforehand, just in case.
# losetup /dev/loop0 /path/to/imagefile.jffs2
Replace '/dev/loop0' with '/dev/loop/0' if you are using devfs. Replace '/path/to/imagefile.jffs2' with the path to your existing jffs2 file. If this doesn't work, you probably don't have loopback device support in your kernel.

3. Emulate an MTD device on the loopback device
# insmod blkmtd erasesz=256 device=/dev/loop0
again, replace '/dev/loop0' with '/dev/loop/0' if you're using devfs.

4. Mount the MTD device
# mount -t jffs2 /dev/mtdblock0 /mnt
Replace '/dev/mtdblock0' with '/dev/mtdblock/0' for devfs. Replace '/mnt' with a suitable mount point in your filesystem. If you don't have a /dev/mtdblock0 (or a /dev/mtdblock/0), create it with this command
# mknod /dev/mtdblock0 b 31 0
then retry the 'mount' command above.

5. Create a new (minimally-sized and cleaned-up) jffs2 filesystem from the old one. Note that this should all be typed in as one line
# mkfs.jffs2 --root=/mnt --eraseblock=262144 --pad --output=/where/to/save/new.jffs2
Replace '/mnt' with the mount point you used in step 4. Replace '/where/to/save/new.jffs2' with the path to where you want the new jffs2 file saved.

6. Clean up after yourself
# umount /mnt
# rmmod blkmtd
# losetup -d /dev/loop0
# rmmod loop
# rmmod mtdblock
# rmmod mtdcore

If step 5 worked, you will now have a new jffs2 file, hopefully smaller than your old one. If it's still not under 22MB in size, you can try compressing it with gzip
# gzip -c /path/to/new.jffs2 > /path/to/new.jffs2.gz
I have never used a .gz file with the "load root" command, but it has been reported to work.