Navigation:

Search



Related Articles

Our Friends

Articles Linux on small footprints
 

Linux on small footprints

This was written by James Crasta .

Table of Contents


1. Overview

So you probably reached this document thinking it's about running Linux on embedded devices. Wrong. I think everyone by now is sick of embedded devices, and if you're not, I for one am. They've been beaten to death. So, this article is a little something different. This is not running linux on MMU-less devices with only 4mb of memory and a pittance of flash. This is how to fit linux onto smaller storage media (be they business card cdroms, small flash USB mass storage devices, flopies, or small hard drives) and getting a usable system out of it. It'll discuss different techniques for booting off of removable media, different techniques for compressing your data to fit on said media, and lots of other interesting stuff.

This document isn't the everything source for booting Linux off removable storage. This will just provide some pointers and ideas to set you on the right course. An easy thing to do is to also look at the myriad of projects that are already out there. There are numerous linux on floppy distros if you search freshmeat.net, for doing neato things on a a floppy. There are also many CD distros, ranging from the mini Linux Bootable Business Card and Damn Small Linux to ones which use the maximum of a cdrom, like Knoppix.

2. Where to begin?

First you need to define what your small footprint is. Is it a 1.44mb floppy, or is it a 200mb hard disk, or something in between? What does it need to run? When you have space constraints, you need to define your list of what specifically you want this distribution to do. A lot of tools are out there, so you don't need to reinvent the wheel.

2.1. What do you need?

For a functional linux, you need at minimum a bootloader, and a kernel. I'd assume you also want a userland, so on top of that you'd need a filesystem of some sort, userland utilities, dynamic linker, and a C library. Then you need library dependencies for all of those userland utilities, library dependencies for those libraries... isn't this fun?

3. Booting

Booting is one of the trickiest steps. It involves a lot, and is usually the worst in terms of the amount of trial and error required in order to get the system working. You usually need a bootloader of some sort, which in turn has to be able to locate a kernel. The kernel after starting up then needs to find a root partition to mount. Sometimes an intermediate step, an initrd partition is needed. I'm going to go over each of the different strategies by media.

3.1. Floppy Disks

For those people still fiddling around with floppies, you have several choices. If you want to put your bootable thing on a FAT filesystem, you can use syslinux to boot off of the FAT floppy. Why would you use a fat floppy? Well, if you needed to edit scripts or files on the floppy quickly from other OSes, you could do so this way.

If you want to use a more unixey filesystem on there, you would probably want to make the floppy use a minix or ext2 filesystem. Minix is preferable because of its small overhead. Bootloaders you could then use would be either lilo or grub.

3.2. CD-ROM

When you're working with a CD, on an x86 this means an el torito boot image. El torito is essentially a BIOS hack that was created in the mid 90's that allows a cdrom to be booted off of a floppy image that has been placed on the CD. The floppy image can be just a linux boot floppy that has cdrom drivers to load further stuff from the CDROM, or it can be something like ISOLINUX, which is a bootloader made specifically for booting off cdroms. The advantage of isolinux is you don't need to mess with floppy images, and you can put your kernel (or kernels) right onto the cdrom. More on this later.

3.3. USB and beyond

How do you boot from a USB mass storage flash key? The answer is, you don't. Well, some BIOSes claim to be able to boot from USB mass storage, but there is no standard spec for doing so. Does it mean it'll boot _anything_ from mass storage? From what I've seen, it seems it can do it from USB cdroms, but not from USB disk devices. Maybe that has changed in other BIOSes, it seems to vary. If you have a system that can boot from a USB mass storage and you'd like to let me borrow it for testing, feel free to contact me. Little to no documentation seems to exist for this.

The obvious issues would be, that once you did get the OS booting, there aren't any bootloaders out there that can recognize USB mass storage. So you'd have to boot straight into your kernel, and then from there attempt to locate the boot device (since hardcoding it in is impractical, there's no guarantee it will be placed in the same scsi slot at boot)

So does this mean you should throw your USB mass storage keychain away? not at all! You can always boot from a floppy or CDROM and then pivot-root to the USB key. Alternatively, you can put your userland on the CDROM, and keep your home directory and data on the key. Then you have a combination business card CD with a key that, when inserted into any system, boots up into your own personal environment where you can access your files.

4. More booting. Loops, initrds, ramdisks

Okay, so your kernel starts. Now what? You probably want a root filesystem. Depending on your approach, and how much space you have, there are several solutions to this.

4.1. Initial Ramdisks (initrds)

Sometimes you might want to start with an initrd first. An initrd (initial ramdisk) is a compressed filesystem image that the bootloader loads, and the kernel can use this as a temporary root in the process of moving to the real root. The initrd can do some basic system setup, initialize some modules into the kernel, maybe scan for hardware, pretty much anything you want. Some people have used the initrd as the main filesystem for their projects, ie don't pivot-mount to another filesystem, and just stay in the initrd. This is somewhat practical, but keep in mind that the uncompressed initrd stays in memory as long as its mounted, so after a certain size an initrd will not be practical anymore.

To make an initrd, you need to create a file of the size of the uncompressed initial ramdisk, and then put all your scripts on there. The initrd can follow any structure you like, and there only is one file that is _required_ to be on there. You need in the root path of the initrd a file named linuxrc. This linuxrc can be any executable type, be it a C program, a shell script, or anything.. as long as it's a valid linux script that you could run at the commandline. The following commands would create a 1200KB initrd:

$ dd if=/dev/zero of=~/myinitrd bs=1024 count=1200
$ mkfs.minix ~/myinitrd
$ mount -o loop ~/myinitrd /mnt
( copy all the files and libraries you'll need in your initrd here.
  You'll probably want to chroot into the initrd to make sure that
  all the library dependencies are met.)
$ umount /mnt
$ gzip ~/myinitrd

4.2. CramFS

For you floppy booters, another VERY SMALL loopback filesystem option exists, the Compressed Ramdisk Filesystem. CramFS has an issue in that it's a read-only FS. This is not a huge issue, it just means that unlike an initrd or compressed loopback where you can always re-mount it and edit it, you need to recreate the cramfs each time from your source files, similar to how the ISO9660 filesystem works. It has extremely good compression though, and very little filesystem overhead, which might make it all worth your while.

In order to make a cramfs, you need to prepare your own directory of scripts, and then get the cramfs utilities from SourceForge. You then need to run the following:

$ mkcramfs ~/mydirectoryofstuff img.cramfs

where img.cramfs is the image you wish to create. You can then point linux at this file as its root filesystem.

4.3. Compressed loopback

So you have a lot of space. Like 50mb, or something enormous, like 200mb. But you need a unix-like filesystem, and don't want to work within the constraints of iso9660 on a CDROM. Or you want to squeeze more out of the cdrom than the normal uncompressed space will allow you. What are your options? The best one at this point is to use the compressed loopback (cloop) module. The cloop module essentially lets you put any filesystem of your choice within a file, but does transparent decompression on it, but doesn't keep the entire thing in memory like initrd does. So either make your ext2/minix/whatever filesystem in a file, or even another ISO9660 filesystem inside the cloop. (yes that's right, an ISO9660 filesystem within another.)

So in this example we'll assume you have a directory in your home directory called ~/loopfiles which will contain everything you wish to put in the cloop filesystem. You then can do something like this:

$ dd if=/dev/zero of=~/looptmp bs=50M count=1
$ mke2fs ~/looptmp
$ mount -o loop ~/looptmp /mnt
$ cp -a ~/loopfiles/* /mnt/
$ umount /mnt
$ create_compressed_fs ~/looptmp 65536 <~/root.cloop

or if you wanted to do it as an iso9660 filesystem, you could do something like this:

$ mkisofs -r ~/loopfiles | create_compressed_fs - 65536 <~/root.cloop

5. Userland

Okay, so we've beaten looping things to death. Now, how do we get a userland? We need to get utilities, and a C library. This is where you need to get intimate with the programs you want. You need to figure out exactly what libraries you need and want.

5.1. uClibc and diet-libc

In many cases, such as any system where you have less than 75mb to work with, you'll probably want to drop the standard glibc for something lighter. The first choice you have is uClibc, the more popular of the two listed here. uClibc can easily fit in about 450k without breaking a sweat. It can be compiled even smaller by dropping things such as locale data and such. Compare this to about 20-40MB for fitting glibc with locale data and you'll see why uClibc wins this discussion.

When you're working with uClibc, you're going to need to create your own build environment, preferably something chrootable, and rebuild all your applications to link to uClibc. You also need to tell all your applications to avoid static linking where possible. While your at it, make sure when you run configure you disable all but the options you absolutely need. Which is why again a chroot is nice, since you can avoid your configure scripts searching the host system for libraries and make sure it only finds libraries available within your sandbox.

So, this dietlibc thing. DietLibC purportedly is smaller than uClibc, but omits even more, so may have issues running things. uClibc provides a good subset of the C library, enough to run even gui apps with things like gtk, whereas it seems like dietlibc is the extreme case of the small libc. I'd recommend dietlibc for these purposes.

5.2. BusyBox

So you need to populate your basic /sbin, /bin and /usr/bin with the basic utilities, enough to get your system up and running, and to run scripts maybe. But the gnu coreutils equivalents are big. When you're working on very tight spaces, like within a floppy, you can't fit these in. So what do you do? Here steps in busybox.

Busybox embeds the functionality of a whole host of unix programs into one. The basic shell utilities like cat, grep, cut, split, some utilities such as init. It includes a basic sh shell, with cd, ls, mkdir, and more. Busybox even has network capabilities. It can do ifconfig, run a dhcp client and/or server.

Essentially once you get busybox, you get the single busybox executable /usr/bin/busybox, which you symlink each application you want busybox to service to.

6. X11?

Surely he must be kidding, you say. X in 50MB? Rest assured, it's possible. You just need to look at all the alternatives. While it would be rather tough to fit a full xfree distribution, you can use some of the lightweight alternative servers, like the freedesktop.org Xkdrive servers. They use the framebuffer driver, so you won't get acceleration, but it's pretty cool for a live demo cd that is the size of a business card.

There are other tricks for getting X really small, but we've almost run out of time, so maybe in a future version of this article I'll cover it. Always make sure you know all the alternatives to the software you're running, to see if there is a way to get it smaller. After a certain point, you won't be able to pack a given app any smaller, but you might be able to do it using a different combination of utilities or programs, in less space.

7. Links