Thin Clients Pay More

by Stephen Sefton

At the Superemos community education programme in Esteli, northern Nicaragua, we use secondhand computers as thin (diskless) clients in networks controlled by a Linux server. Many organizations already benefit from the Linux tools available for setting up such networks. They save money, simplify system administration, enhance security and increase autonomy. They are ideal for our low-budget education programmes in Nicaragua. Plenty of information and know-how on setting up these networks is published on the Web. Although that knowledge can be intimidating to try and make work, the effort certainly pays off.

This article explains how we have been using old hard drives and Flash drives to boot diskless clients over a network. It should be helpful to anybody on a tight budget who wants to offer a large group of people low-cost access to computing facilities. At our project, we are especially anxious that educators realise they can recycle older machines to deliver the latest software. But the principles apply equally to better-resourced outfits of all kinds including commercial businesses and government offices.

Before moving on to explain some of the basics for people with no experience of diskless client networks, I should detail and acknowledge our project's sources of tools and information. We have been using Novell's SUSE Linux 10.0 and Ubuntu's Breezy Badger distribution with a variety of new and old machines and parts supplied to us by the Rotary Club of Toronto-Leaside and by SSC Inc., the publishers of Linux Journal. It's worth pointing out that our machines are all PCs. Optimally, it's worth trying to standardise as much as possible. That's always awkward to do when one depends on donated or inherited equipment.

Among the indispensable tools that make our project work smoothly are the superb diskless client software developed by the Linux Terminal Server Project and the comprehensive library of boot-ROM images (see the on-line Resources). The original tool we used for getting old hard disks to substitute for boot-ROM came from Andy Rabagliati (see Resources).

Diskless Client Network Basics

As in any network, diskless client systems consist of a server connected to clients, in our case by Ethernet cable. Once the server is powered up, the diskless clients receive their operating system from it. As each client is switched on, it learns from its BIOS that no system is available on hard disk. It then tries to boot from the local network (LAN) by sending a request via its network card for a server to give it an operating system. The server receives the request and looks to see whether it has the appropriate operating system to send out. If it does, the client boots up as normal using that operating system. For its users, the client machine works just as if it had its own operating system. In fact, it is receiving its operating system from the remote server.

It took us a while to understand the fundamental components of this concept and how they interact. The first thing to find out is whether a potential client has options in its BIOS allowing the machine to “Boot from LAN” (LAN stands for local area network) via boot-ROM. On some machines this is obvious, and on others, the settings are squirrelled away in suboptions of the main BIOS. On still others it just does not exist. If it is available, it enables the machine to boot through a boot-ROM chip, usually with Pre-boot Execution Environment (PXE) capability located in the machine's network card.

If you find the Boot from LAN option and configure the BIOS to boot from LAN you may well be lucky and everything will just work. But don't be dismayed if it does not. One of our machines with a VIA chipset swore solemnly that it would boot from LAN using PXE and persistently refused to do so before finally deciding one day that it would. Such frustrations are a trivial part of setting up a diskless client network and well worth overcoming in order to get a first-class network facility using whatever machines may be available.

Some machines have the network card integrated into their motherboard. If the network card is not integrated into the motherboard, it usually will be plugged in to the PCI slot. (It is possible to work with machines using older ISA cards, but they require special configuration so we have avoided using them.) If the network card is not integrated into the motherboard, it is unlikely to have pre-installed boot-ROM.

We found two main obstacles to using machines as diskless clients. One was that the potential client machine did not offer a Boot from LAN option. The second was that even if the machine offered to boot from LAN, the network card generally had no boot-ROM. We found we could readily overcome those obstacles by putting the necessary files to imitate a boot-ROM on an old hard drive or on a USB Flash drive. The core of this article is devoted to explaining how simple it is to do so. Doing this completely avoids using floppy disks which, in Nicaragua, have simply become too unreliable.

The clients will work with just 32MB of RAM but seem happier with 64MB. Older machines with processor speeds of just 266MHz work okay, but processors with faster speeds obviously work better. Older mice, monitors and non-English keyboard layouts can be configured on the server if necessary. We found no configuration necessary for the majority of our hardware, thanks to the comprehensive LTSP software.

It is well worth investing resources in the server. We now use 1GB of RAM with a 2.4GHz processor and that provides really fast service for more than a dozen clients using Internet, office and game applications. It should be possible to run dozens of clients off one server if the server has adequate specifications. In this article, there's no space to say much about setting up the server for a thin-client network. A couple of excellent articles explaining how Linux Journal helped us do this have already been written by Kevin Brown (see Resources).

Assembling the Necessary Files

For our project, we use the LILO (Linux Loader) bootloader because all we are interested in is booting Linux. The version of LILO to use is important. We discovered that the latest version of LILO by default insists on using lba32 to manage disk geometry and that gave us problems configuring our Flash drive. Fortunately, we found that older versions of LILO don't impose that option. We copied the LILO we used for our Flash drives from Andy Rabagliati's wizzy package. For convenience, we also copied the boot.b file from Andy's package. To configure old hard drives, we relied on Ubuntu and SUSE's prebundled LILO packages. (See the Configuring Old Hard Drives section for a brief mention on using the GRUB bootloader.)

We also need the relevant boot-ROM images for the different network cards that our boot-ROM disk may end up working with. Our network cards are either 3Com 905, Realtek 8139 or Via-Rhine. We got these image files from ROM-o-matic. It took a certain amount of trial and error to get the images that worked. ROM-o-matic updates its releases regularly. All the releases have similar options, and ROM-o-matic helps keep the trial-and-error process to a minimum by offering a button that gives a list of the cards that particular images will work for.

Once you have selected the card image that is probably the right one, you need to select the image type. Because we are using LILO, we chose the current zlilo image type as well as the older type called lzlilo. We used lzlilo on our Flash drive because we found the newer zlilo images seemed to work only on the hard drives. We have yet to figure out why. It's worth emphasizing that experiment yields invaluable information. Here I summarise only the results of our own experimentation. Other people will certainly get different and very likely better results as they try out their own equipment.

ROM-o-matic offers a Get Rom button to download the image files it produces. That option leads to a prompt allowing you to save the image files in your local directory system. We downloaded the various .lzlilo and .zlilo images we thought we would need for our three types of network card. With those files and the LILO files, we had all we needed to make our boot-ROM disks using either a Flash drive or an old hard disk. So we copied them all to one place in a directory we decided to call /flashlilo. Then we needed to put them onto our boot-ROM disk.

Working with Flash Drives

For newer machines that don't boot from LAN but that do have a BIOS option allowing boot from USB hard drive, a Flash drive that imitates boot-ROM is a handier alternative than an old hard drive. Once one client is booted, the Flash drive can be removed and used to boot another client. We found that we could treat the USB Flash drive as if it were a SCSI hard drive. Plugging the Flash drive in to a convenient USB socket we powered up, although thanks to hotplug, we could have just plugged the USB drive in while the machine was already running. This machine ran SUSE, so the YaST configuration tool recognised the new device and asked whether to configure it. We said no.

To ensure the drive we wanted to use for our boot-ROM was clear of any formatting or partitioning problems, we deleted the existing partitions, as the root superuser, using fdisk, and installed a new bootable partition. (If there is anything on those disks that you need, make copies. Partitioning afresh destroys everything on the disk!) We then used fdisk to partition the Flash drive by typing:

# fdisk /dev/sda

Something very important to note for later use when configuring the bootloader is the number of heads, sectors and cylinders fdisk discovers on the drive. Make a note of these. After using fdisk to set up a bootable partition free of any potentially bothersome history, we were ready to put a filesystem on it. We took the easy option and typed:

# mke2fs /dev/sda1

to put on an ext2 filesystem on the Flash drive. In order to tell Linux what device to mount and where, we used the traditional directory /mnt as our mountpoint, checking first that it was empty. For the Flash drive, we typed:

# mount /dev/sda1 /mnt

Then we copied all the files in /flashlilo to /mnt:

# cp /flashlilo/* /mnt

At this point, we needed to write a configuration file for LILO. Being frightened of vi and emacs, we used pico:

boot = /dev/sda
disk = /dev/sda
   bios = 0x80
   sectors = 62
   heads = 4
   cylinders = 1015
install = /mnt/boot.b
map = /mnt/map
root = /dev/sda1
vga = normal
delay = 30
image = /mnt/viarhine6102.lzlilo
image = /mnt/3c905b.lzlilo
image = /mnt/rt8139.lzlilo

We saved that file to /mnt with the standard name lilo.conf.

The main part of that configuration file applies to the overall boot process before the user selects an option from the final menu. In this part, the first line tells the client machine to boot from the Flash drive. The second line and its sub-lines tells it about the disk geometry so it knows where to put things. (This is where you need that disk information you noted from fdisk!) The install line tells it to use boot.b to install the boot stages.

The map line tells the thin client where to find stuff in a file created by the LILO program. The root line tells it where to find the filesystem. The vga line explains how to output information to the monitor. The read-only option keeps everything from getting interfered with. The delay line tells the machine how long to wait before displaying the prompt.

The image sections of the configuration file offer the client user different boot options. So when the client starts up, LILO offers these image options to the user via a menu with three choices of network card from which to boot: Via-RhineII, Realtek 8139 or 3Com905.

Why are boot.b, map and LILO images referred to as residing in the /mnt directory? The reason is that now we have written the configuration file for LILO, we have to tell LILO to use that configuration file. We can do that only in the directory where we are working, which is where the drive we are working on is mounted. In our case, this is /mnt. The command to tell the LILO version we want to work with to update the lilo.conf file is therefore:

# /mnt/lilo -C lilo.conf

This is fine for the moment because we are in /mnt. But what happens when we unmount the Flash drive, remove it and insert in the machine we hope it will boot? Won't we need to change references in the lilo.conf file? And won't we then get into a manic circle of eternally having to run LILO to reconfigure lilo.conf? No, as it turns out. When we tried booting this in our client machines, it all ran smoothly. So, now that we have our boot-ROM drive, we move out of the /mnt directory and type:

# umount /dev/sda1

before removing the drive from the machine.

Configuring Old Hard Drives

When we first started configuring old hard disks to imitate boot-ROMs, we followed a procedure similar to the one we used for the Flash drive. We had to learn this might mean changing the jumper on the hard disk before connecting it to the machine. (The term jumper refers to a tiny connector located in a set of pins on the side of the hard drive.) It is very easy to change the jumper. Most hard drives have little diagrams on their casing explaining how to set the jumper for the different options. Usually there are three: Master, Slave and Chain Select. Chain Select allows the machine's BIOS to decide what status to assign the hard drive.

Most commonly used PC machines have just one IDE hard drive, which is usually the master drive. Linux identifies that drive as /dev/hda. If the old machine has enough memory and a fast enough CPU, it makes sense to connect a CD-ROM drive with its jumper set to Chain Select or Slave and configure the machine's hard drive directly. However, to save time on installation, we ended up deciding to use a much faster new machine with a newish CD-ROM to configure our old hard drives. That meant simply disconnecting the existing hard disk on the faster machine and connecting our old hard drive with the jumpers set to Master. So once we finish the configuration and we connect it to the motherboard of the diskless client, it will be recognised straight away as the primary master drive.

Whatever method we use to prepare the old hard drive for configuration, we install either Ubuntu's Breezy Badger directly from the CD or else SUSE 10 over our local network. In either case, we do a minimum text-based installation and choose LILO as our bootloader. Once the installation is done, we can edit the /etc/lilo.conf configuration file to add the images exactly as they appear in the lilo.conf file described above for the Flash drive. Finally, we run the line:

# lilo -C /etc/lilo.conf

to update LILO with our new image options.

In relation to the GRUB bootloader, we had an old slow machine already running Linux that we wanted to turn into a client. We found we could get it to boot off a boot-ROM image simply by adding this entry to GRUB's menu.lst file (substituting the name of the appropriate boot-ROM image file):

title Via-Rhine Boot-ROM
    root (hd0,0)
    kernel /boot/via-rhine.zlilo

Before we rebooted, we set the hard drive as the first boot option. In this case, the machine on which we did the configuration has the same kind of network card as a couple of the older machines we want to use as diskless clients, so it was a handy control to make sure the hard drive is doing its job imitating boot-ROM. Once satisfied that everything works, we can transfer the drive we just configured to the machine it will be booting. Alternatively, if we configure an old machine by connecting a CD-ROM drive to it, when done we just disconnect the CD-ROM drive and reboot. We have found this simple configuration procedure also works well on old laptops, so long as they have a built-in CD-ROM and network card.

Configuring the Server for Its Clients

Our system in Esteli now serves nine clients, some that have boot-ROM PXE and the rest with various drives imitating boot-ROM. In the case of the Flash drive we configured to imitate boot-ROM, we just put it in a USB drive on the client machine before starting up. The BIOS needs to be set correctly for each client so that the first boot device corresponds to the relevant disk on that client. To access the BIOS, search the monitor screen when you start the computer.

There should be a line that says something like “Press DEL to enter Set-up”. Whatever the key or combination of keys indicated, this will enable access to the machine's BIOS menus. The configuration of the order of boot devices is usually in the second menu, which should be called something like “Advanced BIOS options”. In that menu, you should find the option to set the first boot device. In the case of the Flash drive, we found that setting the first boot device to USBHDD works fine.

The clients need to get a kernel image from the server. A kernel image is another way of describing the files that make up the operating system software that makes it possible to work with different applications. To get their kernel image, the clients have to provide the network server with their identity and establish a network address. Each client identifies itself by offering the unique code on its network card called the MAC address. In response, the server provides each client with a network address called the IP (Internet Protocol) address.

The clients get this information from the server via a networking standard called the Dynamic Host Configuration Protocol (DHCP). Clients booting with PXE get assigned a dynamic address automatically from a general section of the DHCP configuration file dhcpd.conf. Clients without PXE get a fixed IP address through a specific configuration in dhcpd.conf to ensure they are recognised and can get an appropriate Linux kernel image. We have found older machines like to work with kernel images called vmlinuz rather than bzImage.

In our configuration for each non-PXE client, we told the server's /etc/dhcpd.conf file their Mac address, a fixed-IP address and the kernel image they would like. It may sometimes be necessary to configure the Linux Terminal Server Project (LTSP) package that provides the filesystem architecture for our network. The LTSP lts.conf configuration file can be adjusted when a client is using a mouse or monitor or keyboard layout not recognised automatically by LTSP.

Here is some of our server's dhcpd.conf file:

ddns-update-style ad-hoc;
allow booting;
allow bootp;
subnet netmask {
range dynamic-bootp;
default-lease-time 21600;
max-lease-time 43200;
filename "pxelinux.0";
option root-path "";

host ws001 {
hardware ethernet    00:11:5B:86:46:B5;
filename             "/lts/vmlinuz-2.6.9-ltsp-3";

host ws002 {
hardware ethernet    00:60:08:C6:2B:43;

And here is the main part of our server's LTSP lts.conf file:

        SERVER             =
        XSERVER            = auto
        X_MOUSE_PROTOCOL   = "PS/2"
        X_MOUSE_DEVICE     = "/dev/psaux"
        X_MOUSE_RESOLUTION = 400
        X_MOUSE_BUTTONS    = 3
        XkbLayout          = es
        USE_XFS            = N
        SCREEN_01          = startx

LTSP's package permits a wide range of sophisticated configuration options for multimedia and other applications run off individual client workstations that can be configured in lts.conf similarly to individual workstations in dhcpd.conf. We keep our system simple because we are working mainly with Internet and office applications. In our case, LTSP's default configuration recognised all our various clients' hardware except the keyboard layout, so we added a line configuring a Spanish keyboard.

This technology is incredibly accessible and flexible. For us in Nicaragua, it enables us to offer computer skills training to a large number students on low incomes using old equipment to deliver the latest software. The widely available tools and information mean that even relative beginners in Linux can readily implement such diskless client systems for a broad range of educational, commercial and administrative purposes. Rarely can a bottom line show such a large beneficial return for so modest an investment of resources.

Resources for this article: /article/8699.

Stephen Sefton is an Irish citizen who has worked for nearly 20 years as a community development worker in Central America on a broad range of community concerns including housing, human rights, health care, education and sustainable agriculture. On visits home to Wexford, he watches the progressive embayment of Rosslare Strand with his uncle Christy and wonders how long before the family home slides down the cliff into the sea. He remembers happy walks around the southern shore of Lake Nicaragua and the beach at Curraghcloe.

Load Disqus comments