![]() |
![]() |
|
IBM home | Products & services | Support & downloads | My account |
![]() |
|
![]() | ||||
![]() | Lightweight Linux, Part 1 | ![]() | ![]() ![]() | ![]() |
![]() | ||||
![]() |
![]() | Leverage older hardware and break the hardware/software upgrade cycle
Hardware is only as old as the software it runs: a modern operating system and up-to-date applications return an older system to productivity. This article provides best practices and step-by-step guidance on how to build a working Linux system on older hardware or on modern hardware with limited memory and storage. It's a conspiracy! Too often, modern operating system vendors treat hardware as if it were disposable -- use it for a year and then throw it away. One might be tempted to believe that secret backroom meetings are going on between vendors of operating systems and computer hardware manufacturers. New operating systems and applications demand the latest, most powerful hardware. The newest hardware works best only with the latest, most feature-rich software. I'm sure the churn helps someone's bottom line, but it does nothing for mine. I refuse to bow to the conspiracy. When I came across a mint condition IBM ThinkPad 755C in a local garage sale, I realized that I had an opportunity to make a point. Hardware is only as old as the software that it runs. In this article I will describe how I brought the laptop back to life; and I will describe what you need to do if you find yourself in a similar situation. The usefulness of this material isn't limited to rescuing old laptops from the dump. You might need to build a Linux system to run on hardware with resource constraints, such as in an embedded application. The approach is the same. Strategies and advice Since I was heading into territory I had not explored fully, I chose a path with many small milestones. I bring that approach to this article. Frequent milestones helped me determine whether or not I was making progress solving the problem; frequent milestones will help you debug the process when a step doesn't work as advertised. At several points in this article I encourage you to take your system for a spin, even though the system is not yet complete. These tests will help your judge whether or not your work up to that point is correct. My first bit of advice is to forget about using any of the established Linux distributions. I had originally hoped to avoid starting from scratch by installing an existing Linux distribution. I quickly learned that they all require more resources than were available. Even Slackware, long known for its support of low memory systems, needs at least 12 MB to install the distribution and even then it's a very tight fit. One possibility that you might want to consider before embarking on this journey is to start with and then extend one of the existing "single disk" Linux distributions like tomsrtbt (a single disk rescue floppy distribution), Trinux (a single disk Linux security toolkit), or even Tin Foil Hat Linux (a secure Linux distribution designed for encrypting, signing, and wiping files). I looked at several of these mini-distributions before striking out on my own and I learned a lot in the process. While none of the distributions that I looked at were specifically oriented toward resource-constrained hardware like mine, they did share a common goal -- cramming as much functionality as possible into as small a space as possible. While many of the trade-offs they made to achieve this goal were not acceptable to me, I was introduced to both uClibc and BusyBox, both of which I ended up using. uClibc Rather than use Glibc, I recommend uClibc, a modern, stable, highly compatible replacement for Glibc. uClibc was developed for embedded systems and is therefore intended to be complete but lightweight. Trade-offs between speed and size were decided in the direction of size. In spite of this, in almost all cases, applications and tools compiled against uClibc are indistinguishable from those compiled against glibc. The uClibc Web site (see Resources) lists over one hundred applications that are known or have been reported to work with uClibc. The list includes standard utilities like Gzip and Lilo, as well as slightly less common utilities like Lame (an MP3 encoder) and Freeswan (a VPN implementation). Since I measure the usefulness of a system by the maturity of the tools and applications that run on the system, it was important to me that the C library I chose be capable of supporting the tools I needed. Dietlibc is another alternative to Glibc. My research indicated that while Dietlibc requires less memory that uClibc, it realizes this gain by sacrificing compatibility with Glibc. In the end, I went with uClibc because it appeared to support more of the applications that I needed to use. BusyBox By using BusyBox I conserved precious resources and saved myself a huge investment of time. I found nothing else like it. Ingredients and preparation Begin by downloading the following packages (see Resources for links):
In order to build and link BusyBox with uClibc, you will need to install the uClibc development environment in the /usr directory of the target system, so you'll need write access to that directory. Part of the process involves building a simple root filesystem. I have simplified this step by providing a suitable root filesystem skeleton, complete with the necessary configuration files and device files. You can download the file skeleton.tar.gz from Resources. You'll need to read and digest the necessary documentation, including README and INSTALL documents. There are simply too many options and special cases to cover all permutations in this article. In the sections below I present my recommended configurations. Let's build the kernel. Building the Linux kernel Kernel configuration
Note: Laptop networking may require PCMCIA support. Older laptops won't support the newer Cardbus (32-bit) cards, but that's usually not a problem since there are still many 16-bit networking cards for sale. If you are planning on connecting to the network via wire you will need to select the appropriate drivers under "PCMCIA network device support," which is not included in the table above. I went the wireless route. Many 16-bit PCMCIA cards use the Hermes chipset. You may need to alter the configuration slightly to suit your PCMCIA controller chipset and PCMCIA card. You should configure the kernel to specifically support your CPU. If you're building a kernel for an older machine on a new machine, you'll need to select the appropriate processor such as an Intel 386 or 486. In the interest of saving space you might what to disable everything you don't think you'll need, in particular SCSI support. The following steps build the kernel:
I'll describe how to install the kernel later. Building uClibc uClibc configuration
The three options in the table above make it possible to build and install software like SSH and NFS if you should later choose to do so. You also need to specify the location of the Linux kernel source. The following steps summarize how to build the uClibc package. They assume you've extracted the archive into a directory named uClibc-0.9.15:
The instructions above assume you're building uClibc for a Intel microprocessor. If you're building uClibc for a different microprocessor, create a link to the appropriate Config file in step two, above. The Once the development environment is installed, you can use the uClibc
development tools in place of the standard Glibc-based development tools
by changing the
Once you have changed the PATH environment variable you will find that most development commands (gcc, ld, ldd, etc.) now point at uClibc wrappers. The commands should, however, still work the same. It's very important that you set the PATH environment variable correctly before building any of the software below. The latest release of uClibc (version 0.9.15) won't build out of the box on my Redhat 7.3 system. The technique used to locate the gcc headers changed with the release of version 0.9.12. If uClibc won't build on your system, apply the uclibc patch supplied in the Resources section of this article. It ports the previous technique to the latest release of uClibc. I will describe how to install the runtime environment on the boot and root disks later. Building BusyBox The table below describes that changes you should make to the Config.h file. BusyBox configuration
Make sure you select ASH as your default shell -- it is the most complete Bourne-compatible shell available in BusyBox. It will run most shell scripts, including those necessary to set up networking. If you enable NFS mount support, pay attention to the comment that says you must mount with the "-o nolock" option since you most likely won't be running the portmapper daemon. You must also change the Makefile and enable large file support. Set DOLFS to true. The Building Util-linux Util-linux is easy to configure and build. Type Building E2fsprogs The following steps build the E2fsprogs package.
The undocumented makefile target in the last step creates a TAR file containing the necessary libraries and executables. We will use this to install the package later. Building LILO The Creating the boot disk There are several different ways to build a boot disk. The Linux kernel will boot directly from a floppy disk if configured to do so. Most Linux users boot into Linux with the help of a boot loader like LILO or GRUB, however. The Boot Disk HOWTO (see Resources) describes both of these methods and one or two others. I'm going to describe how to build my version of a LILO based boot disk. I recommend the LILO-based method because the LILO-based method allows parameters to be passed to the kernel at boot time. This is very important when dealing with older hardware, which often suffers from troubling idiosyncrasies. In my case, the Linux floppy driver requires the parameter "floppy=thinkpad" be specified in order to get around problems with the floppy drive on my ThinkPad model. The LILO method needs the LILO executable installed on the system on which you're building the software to make the boot floppy bootable, so you must have LILO installed to proceed. If you can not or will not install LILO, I suggest trying one of the other procedures for creating a book disk described in the Boot Disk HOWTO. You will need to be root in order to perform the following operations:
Now you must copy the kernel from <linux source>/arch/i386/boot directory to the floppy disk and set the ramdisk word. Replace <linux source> in the path below with the directory in which you built the kernel.
In order to make the floppy boot, you must run LILO. First, create a LILO configuration file named /mnt/bdlilo.conf. I created one with the following information: Lilo configuration
The following command puts the boot loader in place on the boot disk.
If you're feeling brave you can now try to boot your target system from the boot disk. You won't get to a command prompt because we're still missing a root disk, but you'll get a feeling for whether or not you've successfully executed the steps above. Creating the root disk VFS: Insert root floppy disk to be loaded into RAM disk and press ENTER The bootdisk we created in the section above holds only the kernel. In order to create a working floppy-based Linux system we need a complete filesystem and the BusyBox software we built earlier. In the Resources section of this article, I provide a link to a file containing a filesystem skeleton. The filesystem skeleton contains the appropriate directory hierarchy and also defines enough devices in the /dev directory to get your system running. To this filesystem, we will add files, libraries, and executables from the packages we built earlier. You will need to be root in order to perform the following operations:
We will now install uClibc and BusyBox onto the new filesystem.
Copy the filesystem to disk and you're finished.
The boot disk and root disk are all you need to boot a system into Linux. The next step is to install Linux on the laptop hard drive. Creating the supplemental disk
We will now install the remaining tools and utilities onto the new filesystem.
Write the files to disk and you're finished. The supplemental disk will be mounted as a normal disk, so it's important not to compress this image.
You now have all of the files you need to install Linux on the laptop on three floppy disks. Installing Linux Figure 2. Loading the root filesystem Once Linux has booted, mount the supplemental disk and copy the files from that disk to the root filesystem on the ramdisk. Once you have copied fdisk, mke2fs, lilo, and their supporting files, you are ready to partition and build a filesystem on the target system's hard drive. Fdisk is a menu-driven utility for creating and manipulating partition
tables. It is relatively easy to use: When partitioning the hard drive, don't forget to add a swap partition. I recommend creating a swap partition of three to four times the size of system memory. Mke2fs creates an ext2 or ext3 filesystem on a partition. The command
Once the hard drive is partitioned and the filesystem is built, mount the hard drive and copy the files from the ramdisk-based root filesystem to the new filesystem. The only files that you will need that are not present on the ramdisk-based root filesystem are the Linux kernel and the LILO configuration file. You can get these from the boot disk that you created earlier. Insert and mount the boot floppy and copy the kernel and LILO configuration files to the hard drive. Place both in the /boot directory of the hard drive filesystem. Rename the LILO configuration file to lilo.conf and edit it so that it looks like the following: Lilo configuration
Finally, install LILO as follows (assuming the hard drive is mounted on /hd):
That should do it. You've built the necessary software, used it to boot the target system into Linux from floppies, partitioned and created a filesystem on the target system, and set the system up it boot directly from the hard drive. Not bad for a day's work! Conclusion Next time we'll build the packages necessary to install Linux on the hard drive of the laptop, and discuss PCMCIA support and network support.
![]()
| ![]() |
![]() |
About IBM | Privacy | Terms of use | Contact |