Building X terminals with Linux

Mike Banahan


In 2000 we abandoned per-seat workstations in favour of low-cost thin-client computers built from PCs about to be scrapped. They provide an environmentally friendly alternative to cluttering up landfill sites, use much less power and create less noise than the typical desktop PC and have proved to be a resounding success for the business. Our cost of ownership has gone through the floor, they require zero maintenance and allow us to switch and swap desks as we wish. It’s hard to find a bad thing to say about them. They have been a pleasure and delight since we first started to use them. We are a demanding group of software developers and yet we think that in many ways they are an improvement rather than a retrograde step. There’s almost a perverse pride in being able to say that our most powerful workstation is a Pentium P90 with 32MB of RAM.

This article is an updated version of the original writeup which was done just after we made the switch.

Building X terminals

I hate the sound of fans. The PC in its modern guise is an evil thing, sitting underneath most peoples’ desks, polluting the office with heat and noise, as well as costing an arm and a leg to maintain. I’ve always wanted to get rid of the monstrosity under my desk and to be able to work in peace and quiet. The classic way to do that is to get rid of the PC and install a diskless workstation of some kind, ideally one with low power consumption and particularly no fans. So I did.

There are lots of forms of workstation: the dreaded NC (now thankfully an idea that is largely defunct), ‘real’ expensive (i.e. Sun or similar) workstations, various other makes and models and those supported by The Linux Terminal Server Project. I decided to have a go at building the latter.

Since first writing this piece, it’s interesting to notice that thin clients appear to have started to gain ground. As well as a large number in use by Windows™ users for the Terminal Server™ and the Citrix MetaFrame™ protocols, there seems to be an increase in the number of VNC-aware thin clients offered for sale commercially. From our experience they are most popular for call-centre or kiosk-style applications

How X Works

Lots of people use Linux, happily accepting the X graphical environment but not really understanding how it works. I was largely in that category myself, but with a least an inkling of what it tries to do.

Unlike the window systems that most people are familiar with, X is inherently networked — the idea is that the display is remote (over the network) from the programs that use it to show their output. As a consequence, an X display provides graphical services to programs that choose to use them, so the X display is called the X server and the programs the clients. This seriously confuses anyone used to thinking of their web browser (for example) as being the client and the remote computer as the server. In the X world client and server are the other way around.

Diagram of X

Most Linux users use the internal network of their PC or laptop to replace the network component shown above, so it looks just like an ‘ordinary’ window system, but even when the client programs and the graphical server are located on the same computer, internal networking is being used. That means that if you know how to authorise a remote client, you can tell it to use your chosen display to do its output. It’s way beyond the scope of a note like this to go into the ins and outs of it, but we find that the ability to run remote client packages is extremely useful.

As just one example, we have a small number of licensed commercial software packages (Star Office, Kylix) sitting on a central server. Our users don’t need minute-by-minute access to those packages on a daily basis, but when they do need it, they simply use ssh over to the host that has the package and run it from there, displaying on their own desktop. Ssh is particularly good for doing that, since it also provides a secure proxy channel for the X data and means that you don’t have to get involved in X authentication issues (a very good thing).

If you haven’t tried doing it before and want to try it, get an X server running on one system on your network (we’ll call it serverbox) and follow these steps to run an application on another system (called clientbox), replacing names as necessary:

Serverbox Clientbox
First of all, give clientbox authority to access your X server: type
xhost +clientbox
to the shell prompt. Then telnet over to the clientbox.
telnet clientbox

Now you have telnetted to clientbox. Your DISPLAY environment variable has probably been set by the telnet/login combination, so this should work:
xclock &
If not, try
DISPLAY=serverbox xclock &
All being well, you will see a clock (presuming xclock is installend on clientbox)

Beware: this is a poor model for granting authority to clientbox; it gives everyone on clientbox the opportunity to grab your keyboard and mouse. Only use it in a trusted environment or for a demo. To learn more about X authentication and permissions, you will have to do some serious background reading.

You can obtain a similar effect if you have ssh set up correctly and use it to connect to the remote system. In that case, ssh ‘tricks’ the remote application into talking to a proxy connection for X so that ssh can transfer the data to your local system, drawing it on the local display. The great benefit of that scheme is that it’s not only secure, but it also hides away any nasty authentication issues from you. In general, that’s the easiest safe way to get remote applications using a local display.

The Linux Terminal Server Project

The Linux Terminal Server Project provides a specialised kernel and configuration that is intended to run on a stripped-down PC with no hard disk. You can boot it from a suitably-prepared floppy or a network card with a boot ROM and it will look for a suitably configured server on your network, download the kernel and suppport files, then start the PC running as a standalone X server. The first one I built used a floppy disk, a cast-off 486/DX-66 motherboard and 16MB of RAM. I powered it from a standard PC power supply that had been removed because of a noisy fan: I took off the lid and cut the wires to the fan to silence it.

Installing the LTSP distribution was pretty easy, simply following the instructions had the X terminal running a couple of hours into the start of the project. They have done a good job of packaging it up for most well-known Linux distributions and the instructions are pretty clear. Making the floppy bootdisk wasn’t too difficult either. Other contributors have taken the basic idea and extended it so that you can boot from non-Unix systems and even load other types of operating system on the terminal.

It’s not ideal to have to boot from floppy, so the next step was to put a boot ROM into the network card. Downloading the Etherboot distribution had been a part of creating the boot floppy — there is some good documentation about how to create bootproms. I looked around and the lowest-cost devices I could find were 27C512 chips, these are 64KB EPROMS. Most boot cards don’t need to be this big, but the smaller EPROMS actually cost more, presumably because of lower volume production.

Since we started the project, the brilliantly named Rom-O-Matic website has popped up, providing configurable boot images for floppies and ROMs for a wide range of network cards. These boot images aren’t specific to the the LTSP project, they’ll load anything if it’s in the right format.

I found that the most effective way of creating the boot ROM was to copy the 16KB of boot image from the Etherboot software into the ROM four times to fill it. This takes care of any confusion by the BIOS about where it should look for the bootable image if the ROM is larger than expected. It takes just a couple of seconds to program the boot ROM in a programmer (if you have one) and the images for NE2000 ISA cards and NE2000 PCI cards both worked well on a motley assortment of odd Ethernet cards in the junk box.

I found that the network cards had to be set up to recognise the boot ROM — none of them did it automatically, so I had to dig hard for the original setup disks, all of which needed to be run under DOS — but once the cards have been told they have a ROM they remember their configuration. If you haven’t put boot ROMs into network cards before it’s disconcerting how hard you have to push them to get them in, particularly since their legs are very fragile. Fortunately I’ve got a hardware background from years ago and hadn’t lost the knack of pre-bending them to fit the slot, then pushing hard whilst listening for the curious scritchy-scratchy click of a ROM sinking home.

Running the X Terminals

The X terminals run with their root filesystems in RAM disk. Workstation-specific files are stored on the RAM disk and the the other files they need retrieved using NFS file sharing over the network — so it’s important to have a reliable NFS server for them to use, that’s the price of doing without a hard disk.

Logging-in is a completely different matter when you have a set of X terminals and no real notion of a ‘home’ system. The standard way of doing it is to use xdm — the X Display Manager. Although it is doubtless a lean, mean and cleverly designed piece of architecture, all I can say as an outsider is that it seems far too complicated for its own good and by no means easy to get to grips with. Here’s my understanding of using the brute:

  1. xdm can be used to start the local X server on your PC (as some distributions of Linux now do by default) then offer the option of logging-in. This can be arranged to run on boot-up so that the system behaves rather like a Mac or Windows PC: it starts up and gives you a windowed interface immediately.
  2. xdm can also be run as a remote service — when your X station starts, you will configure it to contact an xdm server on a specified host and it will offer you an X version of the login prompt for that host.
  3. xdm can be run in a mode where just like above, you contact your specified remote xdm server, but ask it not just to offer you a login on that host — instead it will broadcast to the network for any other xdm servers running and for each one that responds, it offers you the choice of logging-in via them instead.

Both KDE and Gnome now come with their own xdm replacements. They look prettier than xdm (which could only be loved by its mother) but do the same job.

Because we run several hosts that should offer logins, I decided to run xdm in the last of the modes listed, the one that broadcasts for other xdm servers. To do this meant editing the /tftpboot/lts/ltsroot/etc/rc.localfile on the boot server for the X terminal: here is the crucial (changed) line:

echo "/ltsbin/${XSERVER} -ac -indirect ${XDM_SERVER}" >/tmp/start_ws

To get xdm on my chosen server to respond correctly, here is my Xaccess file (it lives in /etc/X11/xdm on standard Red Hat configurations) with comments and blank lines stripped:

*               #any host can get a login window
*               CHOOSER BROADCAST

The standard chooser screen (the one that lists the hosts which responded) sits on a nasty grey background and is as ugly as you can find. To fix it, I renamed chooser to realchooser and created this executable shell script under the name of chooser:

/usr/X11R6/bin/xsetroot -solid skyblue4
exec /etc/X11/xdm/realchooser $*   

and then modified the Xresources file in the directory:

Chooser*geometry:            600x500+300+225
Chooser*allowShellResize:    false
Chooser*ShapeStyle:          Oval
Chooser*viewport.forceBars:  true
Chooser*label.font:          *-*-bold-i-normal-*-240-*
-misc-fixed-medium-r-semicondensed--13-120-75-75 -c-60-iso8859-1
Chooser*Command.font:        *-*-bold-r-normal-*-180-*
#ifdef COLOR
Chooser*Form.background:     gray80
Chooser*label.foreground:    white
Chooser*label.background:    midnightblue
Chooser*Command.background:  gray80
Chooser*internalBorderColor: black
Chooser*Command.font:        -adobe-helvetica-bold-r-*-*-12-*
Chooser*viewport.useRight:   true 

I’d love to pretend that I came up with all that myself, but in reality it’s all plagiarised from either Rich Kaszeta’s Linux X Terminal Pages or the XDM-Xterm mini-HOWTO — a big vote of thanks to both those authors.

This is being written using a Linux X Terminal running on the old 486/fanless PSU combination mentioned earlier. Here it is prior to having a case made for it, in naked glory (you can see that the fan isn’t spinning):

X Terminal minus box

There is currently 40MB of RAM on the board, but it does seem to work just as well with 16MB.

So What’s it Like?

Most of the time it’s a delight to work with. It boots up silently, runs cool mostly (the right-hand heatsink in the PSU does get just a bit too hot for my taste, running somewhere in the region of 120F) and is proving successful after a severe hiccup that almost had me abandoning the project.

What was the hiccup? Everything was working well until our network got busy; at that point the perfomance of the terminal collapsed, rendering it unusable. The slightest hint of network congestion caused minute-long delays in screen refreshes, even characters wouldn’t echo in terminal windows. I knew that X was greedy in terms of network resources, but that was a nasty shock. Fortunately I was able to talk to some people who were using X terminals at local Universities and it did seem that my problem was unusual. Eventually it was traced to a network card problem. The first network card was just faulty — even on an idle network, every fifth ping or so would have a round-trip time of 1 second rather than milliseconds. The replacement card, a PCI Realtek 8029 derivative had been configured with full duplex enabled. Whatever else full duplex is supposed to do, it wrecked performance. Other identical cards with the default non-full-duplex configuration were fine, and so was the errant card when it was reset. The moral of the story is not to give up! Although we haven’t tried it over a period of months yet, some initial tests with the network artificially loaded up to about 80% of capacity show the X terminal still performing acceptably, though there is some evidence of sluggishness at that kind of load. (NB: that last comment is now out of date, we’ve been running the stuff for two years with fine performance).

On the other side: if you are pushing lots of images over your network, then 10Mb/s doesn’t go very far. Running a single remote browser on a site that is rich in animated images chews up some 30–40% of our old Ethernet network. Stopping the images (press ESC) causes the load to drop off instantly. Yet another reason for browsing with ‘Load Images’ turned off. The Linux Terminal Server Project has support for running applications locally and of course a prime candidate would be the browser ... but so far that hasn’t been necessary. More recent browsers like Mozilla and Galeon have options to tell animated images to cycle once only; that seems to be the ideal solution and that’s now what we mostly do.

As an experiment I dug out an ancient 386 DX/33 with 8MB RAM. It booted and ran adequately, though the performance wasn’t great once you started dragging windows around (the video card didn’t help, I had to turn off acceleration to get rid of some pixel problems, the 386 couldn’t be blamed for that). I used it for a few hours and started to get used to it. It would make a serviceable email terminal if you didn’t ask too much of the graphics. A recent attempt to get it going again failed — the motherboard had been left on the windowsill for too long and the BIOS ROM had been erased by sunlight!

It had proved difficult to get hold of a ROM burner for the boot chips so we ended up buying one. If anyone in the UK (it’s not worth the hassle of shipping overseas) wants a boot ROM making, get in touch and we’ll do it at a modest price.

Mike Banahan, 30/September/2000

Update 31st May 2001

This project has been so successful that we have switched to using low-cost X terminals throughout the company. The rather worrying naked motherboard / PSU combination shown in the picture above is still doing sterling service, though the motherboard has been replaced by a cast-off Pentium P90 setup with a huge socket 370 processor heatsink clipped onto it, minus the usual fan. It is noticeably speedier than the 486 when you start dragging full windows around the screen (the entire bitmap, not just a wire-frame) as the KDE and Gnome window managers tend to do.

For safety reasons, the other terminals we use in the company are based on cast-off Compaq ProLinea boxes that we bought in bulk at 50 each (approx US $80). They all came with 32MB of RAM and had a network card and graphics card added to them for an extra 20 (approx US $30). They contain a range of processors ranging from P90 to P166, but crucially each is cooled by an integral fanless heatsink. We accumulated a lot of unwanted 1GB hard drives in the process but managed to sell them to a placement student working here who delights in selling junk via e-Bay. Each of the Compaqs is labelled ‘Property of Arthur Andersen’, so we will have a hard time explaining that to the police if they are ever stolen.

For a while we revelled in the apparent utter soundlessness of our office, then realised that there were still three sources of noise. With the hard drives removed, the Andersen cast-offs still had the fans in their power supplies, creating a noticeable sound (though vastly quieter with the hard drives extracted), the office refrigerator makes an irritating noise and several people started to complain about the ticking of the wallclock.

Silencing the power supply fans in the Compaqs wasn’t as simple as I hoped. I opened one up and cut the wires to the fan. Simple huh? Yes, but the over-engineered Compaq kit then detected a faulty fan and the power supply shut down. Aaargh! Experimentation with a bag of ancient wirewound resistors proved that anything in the 300–800 ohm range would be enough to trick the PSU into thinking that it still had a fan, so a couple of hours work silenced the lot of them. The result was almost total silence .. but as I write (really) that cursed fridge has just started buzzing and as for the clock ... and those blasted birds in the garden ... where’s my shotgun?

So what kind of server do you need to drive these terminals? Presuming that the load would be heavy, a monster fire-breathing device known as tiger was constructed to act as the login and compute server for our users. Sporting twin Pentium III P700 processors, 768MB of RAM and some large-ish UDMA-66 disks it cost about 700 (US $1000) to build. Ten heavyweight users have yet to cause it even to notice their presence. Here is the output of top at this moment, showing that the server is ridiculously over-powered:

 10:13am  up 18 days, 19:15, 12 users,  load average: 0.00, 0.04, 0.08
162 processes: 160 sleeping, 1 running, 1 zombie, 0 stopped
CPU states:  0.2% user,  0.8% system,  0.0% nice, 98.8% idle
Mem:   841552K av,  498520K used,  343032K free,  206220K shrd,  205048K buff
Swap:  262544K av,    5036K used,  257508K free                  111880K cached  

That level of use started to flood the old 10Mb Ethernet, so we invested in a 100Mb card for tiger and plugged all of the X terminals (still running at 10Mb) into a 100/10Mb Netgear switch which was laughably low-cost.

Overall we have plenty of spare capacity and can add new staff at a cost of about UK140 per seat (US$210) excluding the monitor — half the cost for the X-terminal and presuming the same again for capacity on the login/compute server. Our investigations of the cost of using an alternative such as Windows Terminal Server, Citrix ICA terminals and other proprietary equivalents has us holding our sides in laughter.

We do occasionally have use Internet Explorer to check the effect of our web-building activities for customers like The Register. There is one PC on our network running Windows 98 (everyone has to know where it is so it can be rebooted regularly) which has had a VNC server installed. Using the VNC viewer, any of us can take control of it and bring it up onto our desktop, providing us with the rich cultural experience of seeing the two different worlds side by side.


I’d also like to thank IBM for the loan of a NetVista thin client device which works happily alongside all the homebrewed terminals.


By rights, any project like this should have its drawbacks and detractors too. Well, it’s hard to think of much wrong with it. Once disadvantage is that the office is noticeably colder in winter now (far less heat from the PCs), but we win in the summer because it’s cooler. Admittedly, in Yorkshire the winter seems a good deal longer than the summer so overall you could call that a loss.

At one point we had a slight problem with the central server and that brought home the fact that it’s a good plan to have a standby available. If everyone uses one server and it’s down, then so are they. For the money we saved, it’s hard to think of a good reason for not having one.

If you need really zippy graphics performance, this is not a good solution. Running packages like Star Office and Mozilla you notice a slight latency. It’s not a problem at all, but when you start trying to manipulate huge images or view streaming video then you will want a traditional workstation solution. None of our developers do, but full-time graphics people certainly would. The nice thing about the thin-client approach is that it’s not either/or, you can mix both side by side.

Hats off and a big vote of thanks to the LTSP people. A great package, well implemented and documented. It’s hard to ask for more.

Useful Links