


I had the need of booting Linux from a compact flash card in an embedded device. And for producing small quantities in-house it was necessary to have disk images from these flash cards that could just be dd'ed onto the the flash cards. Since it took me some time to figure out how to do that I've written this guide in hope others may find it useful.
Our first method to get these disk images was to boot the embedded device via Knoppix, mount the compact flash, copy the necessary files via scp onto the compact flash, chroot onto the flash, run LiLo and reboot. Afterwards we'd dd the complete flash content into a file. Not very entertaining. And especially hard to automate when you have a new release very often.
So we wanted to automate the image creating process as much as possible. Using an USB CF reader/writer we thought this shouldn't be too hard, but it turned out that when we copied the files onto the flash and chroot'ed into it lilo refused to run (can't remember why, sorry).
So we got the idea of producing bootable mini-images, where we would mount the partition using the loopback device, copy the files in, unmount the image and dd that complete image onto the compact flash (complete with MBR, partition table, everything).
Problem is, again lilo is making problems: you can't just update the kernel by copying a new one over the old one. You have to run lilo again. And grub was out since neither of us managed to get to work (while grub seems to be very good, the configuration is an unnecessarily hairy nightmare 1). Alternatives: booting DOS, using LOADLIN or SYSLINUX. Obviously, SYSLINUX is the cleaner solution.
This simple technique described can also be used with any other medium, like USB sticks for example.
And this is how you do it:
Insert CF into reader/writer. We assume that the CF is now accessible as /dev/sda.
Since our raw CF's had lots of garbage on it we zero out the complete CF (helps compressing the image later on 2).
Create partitions: we need at least one boot partition (FAT12 or FAT16, but not FAT32) and a root partition (we used Ext3).
Format the partitions.
Install SYSLINUX on boot partition.
Install master boot record (found in SYSLINUX source directory).
Mount the boot partition.
Copy the kernel image onto boot partition.
Create SYSLINUX configuration file.
Umount the boot partition.
Save the final image.
You can then mount the root directory and copy all your files into it, and even update the kernel by just copying a new bzImage onto the boot partition. No need to run any program like LiLo afterwards.
If you just want to copy the partitioned space then you may want to read on about mounting the disk image and then come back here: you need to calculate the size, which is (<end block number of the last partition> + 1) * 512. Then give dd the additional option count=<size>.
There are two ways to mount the partition.
First, we need to determine the offset of the partition. This is quite easy: just type fdisk -ul <device>. The option -ul means list the partitions on the device and assume a unit size of 512 byte. This looks something like this:
Now all we need to do is a little math to get the offset: we need to multiply the start block by 512. E.g. if we wanted to mount the first partition we'd have an offset of 62 * 512 = 31744. The second partition has an offset of 19840 * 512 = 10158080. Now that we have the offset we can mount the partition:
This would mount the second partition on /mnt. Linux recognizes it as ext3 if it is formatted as ext3 and the kernel supports ext3, so no need for a -t ext3 option to mount.
There is also a hard way to find the formatted partitions if you can't calculate the offsets for some reason:
If there is a partition within the first 10000 blocks, it gets mounted eventually :-) Just type "mount" to get the offset...
After we've unmounted the disk image we can now just dd the disk image to a new compact flash:
Easy as that.
Now a little trick (please let me know if you know a better way): in order to force Linux to re-read the partition-table after we've written a disk image with partition table to an empty compact flash we do this (maybe this isn't necessary, for some reason it was for us).
This document was written and is ©opyrighted 2003,2006 by Marc Haisenko. Thanks to the SYSLINUX author H. Peter Anvin for finding an unnecessary step in the creation process. This moved to the chapter "Final comments". If you have further comments/additions/corrections please mail them to me. You may copy and distribute this document as long as you include this credit section and my name. You may modify it and add your name to this section as well.