The K-Zone: Running Linux and XFree86 on a Sun Javastation

Overview

This document describes how to set up one or more Sun JavaStations (particularly the JavaStation-1 or `Mr Coffee' variety) as X terminals by running Linux and XFree86. It also suggests why you may wish to do such a thing.

Scope of this article

This article is intended to supplement, not replace, the `official' JavaStation-HOWTO, available from the Linux Documentation Project. I assume that the reader has access to the HOWTO, and will want to read it. The HOWTO contains a lot of information about the different JavaStation models and their architectures. This article does provide some general information about the JavaStation boot process, and how to configure a server to support it, but mostly it is about how to produce a kernel with embedded X server that will boot straight to an X session.

Why use JavaStations?

Sun's JavaStations can be made into serviceable X terminals by running Linux and XFree86 on then. Performance is not outstanding, but the machines themselves are diskless and therefore mostly maintenance free. It is possible to embed an X server and all the required supporting software into a kernel image, and transfer the whole thing over the network in one operation. This makes the start-up process comparatively fast. JavaStations are obsolete, and are no longer made by Sun, but some models are widely available second-hand. UK prices start at about UK£ 20; ebay auctions have then changing hands for about $10. There is probably no cheaper way to get a useable X terminal without resorting to crime.
      The most rudimentary, and therefore least expensive, JavaStation is the JavaStation-1, colloquially referred to as `Mr Coffee'. In appearance it is a flat, squat box, light grey with (usually) a Java `coffee cup' logo on the front. Although it is not techically outstanding, the techniques described in this article will give you an X terminal that will boot from cold in about 40 seconds; alternatively the JavaStation can be used to compile kernels, etc., provided you aren't in a hurry. This article focuses specifically on the Mr Coffee model, although some of it is relevant to other models as well. Do be aware, however, that the JavaStation-1 and the superior `Krups' model are very different internally, particularly in their graphics hardware.
      The basic Mr Coffee is supplied with 32 Mb RAM; to use X you probably need 64 Mb. A suitable memory stick is not expensive (if you can still get one). The JavaStation-HOWTO describes the type of memory required and how to fit it.

Assumptions

This document makes a number of assumptions.

Initial info and preparation

You will need to obtain, or decide, the following information before starting.

Background

Mr Coffee

Mr Coffee is a diskless Sparc system with 32-bit `4m' architecture. It has a single ethernet port, PS/2 keyboard and mouse connectors, and a Sun TCX graphics adapter. This is capable of 1024x768 resolution, 70 Hz refresh rate, and 8 bits-per-pixel. There is a Crystal sound chip, but to the best of my knowledge no-one has got it working under Linux. There is a single 9-pin serial connector, which can be used to attach a serial terminal if required.
      Because it is diskless, the kernel and (at least) root filesystem must be supplied over the network. Typically a JavaStation will use TFTP to retrieve the kernel, and NFS to mount the root filesystem. However, Linux allows a root filesystem to be compressed and embedded in the kernel image; this makes the use of NFS unnecessary for small filesystems. Technical limitations -- discussed below -- restrict the size of the root filesystem to about 8 Mb. This is (just) enough to accomodate an XFree86 kernel and the essential shared libraries. To run a simple X server, the `embedded root' approach is, I believe, far superior to use of NFS.

Mr Coffee boot sequence

The usual way in which diskless Unix workstations retrieve their kernels is by making a RARP request to determine their own IP numbers, and the server that will supply the kernel, and then using TFTP to retrieve the kernel. However, the boot PROM in many Sparc machines, including most JavaStations, is unable to load a Linux kernel directly (for reasons related to memory management that I don't event pretend to understand). Happily, there is a solution: use a two-stage boot process. The first stage retrieves an intermediate boot loader, and the second has the intermediate loader retrieve and execute the real kernel. A suitable intermediate loader is PROLL, written by Pete Zaitcev of RedHat. Download details are given later. Note that there are different PROLLs for different JavaStations.
      The need for an intermediate loader means that Mr Coffee follows this procedure when booting. To a large extent, what happens next rather depends on the kernel. Because there is no straightforward way to enter boot parameters on Mr Coffee, we must compile the kernel to use an NFS root by default, or to use an embedded root filesystem by default. We can't select these options at boot time. We must also compile the kernel to negotiate its IP configuration with the server, rather than supplying the information on the boot command line. Some Linux kernels will try DHCP and BOOTP automatically if support for IP negotiation is compiled in, but some will not. This issue is discussed in more detail later.
      So from here on, we can't say for sure how things proceed, but a typical procedure will be as follows, if we are using an NFS root filesystem. If we are using an embedded root filesystem, the kernel image will have contained the root filesystem so the JavaStation will have retrieved it along with the kernel in the TFTP download. The boot procedure is then something like this.

Obtaining Linux and associated software

Obtaining PROLL

You can download PROLL, the intermediate boot loader, from Pete Zaitcev's Web site. There are precompiled versions for the various JavaStation models, and also the source. A binary will do for now, but you may find that you need the source later.

Obtaining kernels

Assuming that you don't have the apparatus to compile Sparc Linux kernels at this stage, you will need a precompiled Sparc Linux kernel to get started. There are a few JavaStation-ready compiled kernels available on the Web; Here are the kernels that I use.
NFS root kernel This kernel (2.4.2) is compiled to use an NFS root by default, and to use DHCP for IP negotiation. To use this kernel, your exported root filesystem should have an /etc/fstab that mounts any other filesystems that will be required (/usr, homes, etc). The kernel is also compiled with EXT2 filesystem and initial RAMdisk support, so it can be attached to an embedded root filesystem. If an embedded root is found, this will over-ride the NFS root mount. Loadable module support is enabled, but no modules are actually required to boot.
RAMdisk kernel This kernel (2.3.99) contains an embedded root filesystem, and should boot without any additional support. There is just enough software in the root filesystem to mount additional filesystems using NFS (but this will be very slow; no portmapper). With this kernel you can mount / manually from a server and then use chroot to make this the new root. You can then mount /usr and perhaps /usr/local under this new root. Provided that your `new' root filesystem contains kernel source and gcc, you can compile a kernel with NFS support. This is how I generated the previous kernel; none of this is straightforward, however.
The JavaStation-HOWTO lists a number of other places where precompiled kernels may be obtained.

Kernel gotchas

No boot prompt. It is difficult to get to the boot prompt on a JavaStation, particularly the Mr Coffee model. This means that precompiled Sparc Linux kernels, unless specifically intended for the JavaStation, may not work. For example, on an Ultra 10 I can get the boot prompt and do this:
ok> boot net ip=dhcp
to force the use of DHCP for IP negotiation. Alternatively, I can add a line append="ip=dhcp" to silo.conf if the machine is to boot from a hard disk.
      Neither technique is practical on Mr Coffee. Now, it appears that some Linux kernels do not do IP address negotation by default even if compiled for NFS root. Presumably the logic is that the administrator will use LILO/SILO/boot prompt to select the negotiation technique to use. This means that if you want to use one of these kernels then you will need to compile the kernel to force autonegotation. For example, modify the kernel .config file with the line:
CONFIG_CMDLINE="ip=dhcp"
I know this problem affects version 2.2.16, and there are reports of similar problems with other kernels. The symptom of the problem is that the kernel boots and gets as far as mounting the root filesystem using NFS. This then fails with error code -11 or -13 (no error message) because the JavaStation does not have a valid IP number at that point. 2.4 kernels seem OK in this respect, as do kernels earlier than 2.2.12. Required features. Undoubtedly the best way to get a kernel that does exactly what you want is to compile it yourself. If you do this, keep in mind the following points.

Obtaining filesystems

Undoubtedly the best way to get a working root filesystem is to build it on another machine with Sparc 4m architecture (with CD-ROM, hard disk, etc), get it working, make whatever small modifications are required, then copy it in its entirety to the exported directory on the server. I have had success with SuSe 7.1 for Sparc. Alternatively, if you have a tolerably fast Internet connection you can download complete /, /usr and /usr/local file systems from UltraLinux. These filesystems will require some changes for your system. At the least the network configuration in etc/sysconfig/network* will need updating. The /usr/local filesystem includes gcc and all the supporting software needed to compile a kernel. It does not, however, include the kernel source itself; you will need to download this separately if you need to compile a kernel.
      If you just want to run an X server, here are two minimal filesystems that will do what you need, an NFS root version and an embeddable version. In fact, there is very little difference between the two; the embeddable version does not include the RPC portmapper as it does not require NFS. Other than that, the most important difference is in the /etc/vfstab file. The start-up script assumes that the root is initially mounted read-only (the only way to change this on a JavaStation is to hack the kernel), and must re-mount it read/write. To do this fstab must reference the correct (NFS or RAMdisk) filesystem.
      I have taken some trouble to make these filesystems as small as possible; I believe that they are close to the minimum size required to run an X server (give or take a few kilobytes). This does mean, however, that they won't be useful for anything except an X server; there is no way to log in locally, for example.

Setting up your server

Overview

There is no particular reason to use a Linux-based server to supply Linux to the JavaStations; the server will not, of course, execute any of the code it will be supplying. I understand that some success has been reported with Sun Sparc servers running Solaris, for example. Of course, it will make life much easier if the server is a Sparc Linux machine of the same architecture as the JavaStation. This makes it very easy, for example, to compile code to run on the JavaStation instead of using the JavaStation itself. It would also be possible to share some disk partitions (e.g., /usr/local). However, these things are luxuries, not necessities. For a server I am using RedHat version 7.0 on an Intel Pentium III system, and this works fine. I am fortunate enough to have access to a Sun Ultra-10 running SuSe Linux for compiling kernels on, so I don't need to use the JavaStation for this. I will assume that your server is a Linux system, but not necessarily the same architecture as the JavaStation.
      To act as a boot source and root filesystem for Mr Coffee, or other JavaStation models, the server needs to support the following services.

Setting up RARP services

Your server needs to support RARP services, as the JavaStation will use RARP to get its initial IP number. A RARP server (rarpd) is provided with most Linux distributions. Conventially, the configuration data goes into /etc/ethers. You need a line like this for each JavaStation:
8:00:20:86:FC:E2 javastation1   # 192.168.1.40 (javastation1)
Substitute your own MAC address and hostname as appropriate. Note that the section following the # is just a comment; the name javastation1 in this example must resolve to a real IP number using whatever method your server normally uses (DNS, hosts). For example, I have in my /etc/hosts:
192.168.1.40	javastation1
192.168.1.41	javastation2
...
After editing /etc/ethers, restart the rarpd server, e.g.,
sh /etc/init.d/rarpd restart

Setting up TFTP services

The TFTP server is typically launched from inetd or xinetd, so these will need to be configured. Most distributions now use xinetd, and TFTP will probably not be enabled by default. Typically you will need to edit /etc/xinetd.d/tftp so that it looks like this:
service tftp
{
        socket_type             = dgram
        wait                    = yes
        user                    = root
        log_on_success          += USERID
        log_on_failure          += USERID
        server                  = /usr/sbin/in.tftpd
        server_args             = -s /tftpboot
        disable                 = no
}
The argument -s /tftpboot is most important. This tells the TFTP server that requests for files that don't have absolute pathnames are to be delivered from the directory /tftpboot. The JavaStation will not use absolute pathnames, and without the -s argument the kernel download will fail.

Setting up DHCP/BOOTP services

The JavaStation will use either or both of these for IP negotiation. Since most Linux DHCP servers support BOOTP as well, it makes sense to install a DHCP server. However, it is important to bear in mind that you probably don't want dynamically-assigned IP numbers for your JavaStations if you are using an NFS root (this is a world of pain). Typically the configuration will be supplied in /etc/dhcpd.conf, and it will look something like this:
subnet 192.168.1.0 netmask 255.255.255.0 {
        range 192.168.1.20 192.168.1.39;
        option subnet-mask 255.255.255.0;
        option routers 192.168.1.254;
        option domain-name-servers 192.168.1.254;
        option domain-name "mydomain";
}
group {
  host javastation1 {
    hardware ethernet 08:00:20:86:fc:e2;
    filename "C0A80128";
    fixed-address javastation1;
  }
  host javastation2 {
  ...
  }
}
Note that the JavaStations get fixed IP numbers, whether they make BOOTP or DHCP requests. The filename entry tells the JavaStation which filename to request by TFTP to obtain a kernel; in practice Mr Coffee does not seem to use this entry, although other JavaStations might.

Configuring /tftpboot

There is no theoretical reason why a directory called /tftpboot must be used; however, this location is hard-coded into the Linux kernel in a number of important places, so it's hardly worth changing it. In this directory you will need one copy of each of the following, however many JavaStations are supported. Then for each JavaStation you will need the following. In summary, with three JavaStations having IP numbers 192.168.1.40-192.168.1.42, you will need a /tftpboot something like this:
lrwxrwxrwx    1 root     root           42 Aug 21 10:35 192.168.1.40 -> /javastationroot/javastation1/
lrwxrwxrwx    1 root     root           42 Aug 21 10:35 192.168.1.41 -> /javastationroot/javastation2/
lrwxrwxrwx    1 root     root           42 Aug 21 10:35 192.168.1.42 -> /javastationroot/javastation3/
lrwxrwxrwx    1 root     root           19 Aug 20 10:16 C0A80128 -> proll.mrcoffee.ID13
lrwxrwxrwx    1 root     root           19 Aug 20 10:16 C0A80129 -> proll.mrcoffee.ID13
lrwxrwxrwx    1 root     root           19 Aug 20 10:16 C0A8012A -> proll.mrcoffee.ID13
lrwxrwxrwx    1 root     root           12 Aug 21 09:20 C0A80128.PROL -> vmlinux.aout.242
lrwxrwxrwx    1 root     root           12 Aug 21 09:20 C0A80129.PROL -> vmlinux.aout.242
lrwxrwxrwx    1 root     root           12 Aug 21 09:20 C0A8012A.PROL -> vmlinux.aout.242
-rw-r--r--    1 root     root        52732 Aug 20 10:14 proll.mrcoffee.ID13
-rw-r--r--    1 root     root      1390585 Aug 23 00:07 vmlinux.aout.242

Configuring exports

If you are using an NFS root, you will have to configure the server to export the root directories, plus any others required by the JavaStations. A simple solution is to have separate root filesystems for each JavaStation, exported read/write, and shared /usr and /usr/local exported read-only. So /etc/exports will look something like this.
/tftpboot/192.168.1.40 javastation1(rw,no_root_squash)
/tftpboot/192.168.1.41 javastation2(rw,no_root_squash)
/tftpboot/192.168.1.42 javastation3(rw,no_root_squash)
/javastationroot/usr *(ro)
/javastationroot/usr.local *(ro)
Note that although /tftpboot/192.168.1.40, etc. is only a link to the real root filesystem, it is the link that must be exported, not the target. This is because it is the link in /tftpboot that will be the subject of the mount request.
      It is possible, in fact, for the JavaStations to share most of the contents of the root filesystem, which can be mounted read-only. Of course, there must be some read-write area for temporary files, etc.

X Issues

To run XFree86 you will need three things: a server, a configuration file, and some fonts.

X server

To the best of my knowledge the only XFree86 server that works at all is the one that uses the Linux framebuffer driver (rather than communicating directly with video hardware). Servers for Sun hardware like Xsun don't seem to work because they require a source of raw keyboard data -- not available on JavaStations, as they use PS/2 keyboards.
      Very important: the framebuffer server with versions of XFree86 later than 3.3.3 will not work with JavaStations, except perhaps with a lot of hacking. The problem is that these servers detect graphics accelerator hardware that they don't recognize; instead of continuing in un-accelerated mode they just give up. Earlier versions seem to behave more sensibly.
      If you don't want to go to the trouble of obtaining and building XFree86, here is an X server binary of the framebuffer server that works with Mr Coffee (and probably with Krups as well). This X server is included in the root filesystem examples described above as well. The server looks for a configuration file called /etc/XF86Config.

XF86 config

Because we have to use the framebuffer driver, the XF86Config file is surprisingly simple. Here is the whole thing.
Section "Files"
   RgbPath    "/usr/X11R6/lib/X11/rgb"
#  FontPath   "/usr/X11R6/lib/X11/fonts/misc/,/usr/X11R6/lib/X11/fonts/75dpi/....
   FontPath   "tcp/fontserver.somewhere:7100"
EndSection

Section "ServerFlags"
EndSection

Section "Keyboard"
   Protocol        "Standard"
   AutoRepeat      500 5
   LeftAlt         Meta
   RightAlt        ModeShift
   ScrollLock      Compose
   RightCtl        Control
   XkbKeycodes     "xfree86"
   XkbTypes        "default"
   XkbCompat       "default"
   XkbSymbols      "us(pc101)"
   XkbGeometry     "pc"
   XkbKeymap       "xfree86(us)"
   XkbRules        "xfree86"
   XkbModel        "pc102"
   XkbLayout       "us"
EndSection

Section "Pointer"
   Protocol        "GlidePointPS/2"
   Device          "/dev/psaux"
   BaudRate        1200
   Emulate3Timeout 50
   Resolution      100
EndSection

Section "Monitor"
   Identifier      "MyMonitor"
   VendorName      "Dunno"
   ModelName       "D1"
   HorizSync       31.5-37,55-65,100-200
   VertRefresh     60-130
EndSection

Section "Device"
   Identifier      "fb"
   VendorName      "fb"
   BoardName       "fb"
EndSection

Section "Screen"
   Driver          "fbdev"
   Device          "fb"
   Monitor         "MyMonitor"
   BlankTime       0
   SuspendTime     0
   OffTime         0
   SubSection "Display"
      Depth        8
      Modes        "default"
   EndSubSection
EndSection
There are a few things to note.

Fonts

XFree86 can use locally-installed fonts, or a font server. If you are using an embedded root filesystem you will have to use a font server: the basic set of fonts requires over 10 Mb, while the whole root filesystem has to fit into 8 Mb. The font server can run on any machine, but it makes sense to run it on the same server that is providing the applications themselves. Philosophically, fonts belong to applications, not to workstations, anyway. The XFree86 font server is called xfs, and is supplied with most Linux XFree86 distributions. Your server does not need to be running an X server itself to act as the font server; however, if it is running X then the same font server can serve both the local display and the JavaStations with no problem. This has the additional advantage of centralizing font management.
      Although XFree86 includes a font server, it will probably not be configured to support networked operation. To fix this, typically remove the line
no-listen = tcp
from /etc/X11/fs/config.
      XF86Config needs to indicate the source of fonts, as shown above.

Starting the X server

Most Linux distributions have X started from a display manager like xdm or kdm. This is meaningless for a JavaStation; you will never want to log into it as a user and run software on it (unless you've got plenty of patience). If you know in advance what server is going to be hosting the X session, you can start the X server directly like this:
X -query 192.168.XX.XX
Using numbers here, rather than names, means that when you build the embedded root filesystem you won't have to include any name resolution software or libraries (saving a couple of Megabytes).
      Of course, the server selected must itself be running a display manager, and be configured to accept remote sessions. With XFree86 and the xdm display manager, this is configured in the file Xaccess. Alternatively, if you have a host that is prepared to respond to a broadcast session set-up request, you can start the X server like this:
X -broadcast

Building an embedded-root X server

If you only want to use the JavaStation as an X server, then I suggest that using an embedded root filesystem is the sensible choice, for the following reasons. Limitations of PROLL mean that the entire root filesystem must fit into about 8Mb. This has to include the X server, shared libraries, init program and some configuration files. If you only want to run an X server, then that's more-or-less all you will need.
      Of course, picking apart a standard Linux distribution to find the minimum set of files to be embedded is not really straightforward. As a starting point you may wish to use my embedded-X filesystem as described above; this expands to about 7 Mb, so it just fits. Look in the file CONFIGUURE for information about changes that you may have to make. When building the filesystem, bear in mind the following.
      To embed a root filesystem you should do something like this. If you get the message:
Unable to mount root fs on 1:0
or similar, then probably your kernel does not have ext2 support compiled in (don't forget, you can't compile it as a loadable module, because there's nowhere to load it from!). Alternatively one of the steps in construction of the filesystem wasn't done properly, or the filesystem is too big.
      I use a JavaStation every day, and I can confirm that the steps described above -- carried out properly --- do work, at least on Mr Coffee. They may work on Krups, but I haven't tried it.

Unresolved and partly-resolved issues

Screen refresh rate

The JavaStation starts up with a display configuration of 1024 x 768, 60 Hz. The hardware is in fact capable of 1024 x 768 x 70 Hz, which gives a much nicer picture. Most modern monitors are able to operate (easily) with these settings.
      How can we change these settings for the X server? On ordinary Sparc systems there are usually three ways. Sadly, none of these methods work with the JavaStation. The first technique -- using the boot prompt -- won't work, because (a) we don't get a boot prompt and (b) PROLL would ignore the video settings even if it got them (because, apparently, older OpenBoot PROMs fail otherwise). The second and third both fail, I think, because of problems with the kernel TCX driver. fbset neither reports nor accepts `meaningful' values of timing parameters. I am investigating this problem.
      A partial solution is to hack PROLL to supply a different screen configuration, provided you can calculate the appropriate video timings. For example, to get 1024 x 768 x 70 you need to change the vertical frequency, pixel clock and (strictly) the horizontal blanking porch. In the PROLL source, you need to edit mrcofee/openprom.c as follows:
From: static int hbporch = 0xa0;
To: static int hbporch = 0x90;

From: static int pixfreq = 0x03dfd240;
To: static int pixfreq = 0x47868C0;

From: static int vfreq = 0x3c;
To: static int vfreq = 0x46;
Disclaimer: these figures are based on a VESA modes table and I believe they will be supported by most modern monitors; but use at your own risk. please don't complain if your monitor blows up. Don't forget to recompile in 32-bit mode if you are using a modern Sparc to do the job. If you are compiling on the JavaStation this will be the default. In addition, don't forget to run elftoaout on the resulting executable, as it needs to be in `aout' format. Here is a compiled binary with these changes inserted.
      The bad news is that whether this modification works depends on what kernel version you are using. I am investigating this problem also.

Sound

I have had no success with getting sound to work on a JavaStation; to the best of my knowledge, neither has anyone else. The sound device is a CS4231 (on SBus), for which a driver is readily available. However, sending a .au file to /dev/audio results in about 200 msec of sound only. The driver won't compile as a loadable module, only directly into the kernel, although it is an option that is offered. This suggests that some work needs to be done on the kernel and/or driver. Sadly, I don't have time for this.

StarOffice

Sun's StarOffice did not work for me when using an NFS-mounted root filesystem. It did work, however, when using an embedded root. This was the case even though the filesystems were identical: same X server, same font server, etc. Answers on a postcard, please...

Acknowledgements

Thanks to Pete Zaitcev and Eric Brower for their advice and assistance.
©1994-2006 Kevin Boone, all rights reserved