Next Previous Contents

2. Installation

2.1 Background

The aim of this conversion is to leave you with a system which can build and run both a.out and ELF programs, with each type of program being able to find its appropriate breed of shared libraries. This obviously requires a bit more intelligence in the library search routines than the simple `look in /lib, /usr/lib and anywhere else that the program was compiled to search' strategy that some other systems can get away with.

This intelligence is centralised in a dynamic loader, which exists in only one --- or two --- places on the system. For a.out programs, it's called /lib/ld.so, and for ELF programs it's /lib/ld-linux.so.1. The compiler and linker do not encode absolute library pathnames into the programs they output; instead they put the library name and the absolute path to the appropriate dynamic loader in, and leave that to match the library name to the appropriate place at runtime. This has one very important effect --- it means that the libraries that a program uses can be moved to other directories without recompiling the program, provided that ld.so (ld-linux.so.1; whatever) is told to search the new directory. This is essential functionality for the directory swapping operation that follows.

The corollary of the above, of course, is that any attempt to delete or move ld.so or ld-linux.so.1 may cause every dynamically linked program on the system to stop working. This is generally regarded as a Bad Thing.

The basic plan, then, is that ELF development things (compilers, include files and libraries) go into /usr/{bin,lib,include} where your a.out ones currently are, and the a.out things will be moved into /usr/i486-linuxaout/{bin, lib, include}. /etc/ld.so.conf lists all the places on the system where libraries are expected to be found, and ldconfig is intelligent enough to distinguish between ELF and a.out variants.

There are a couple of exceptions to the library placement:

2.2 Before you start --- Notes and Caveats

2.3 Ingredients

Anything in the following list that I describe as being ``on tsx-11'' can be found in ftp://tsx-11.mit.edu/pub/linux/packages/GCC/, ftp://sunsite.unc.edu/pub/Linux/GCC/, and at many mirrors. Please take the time to look up your nearest mirror site and use that instead of the master sites where possible. It's faster for both you and everyone else.

These packages (either the listed version or a later one) are required. Also download and read through the release notes for each of them: these are the files named release.packagename. This applies especially if you get newer versions than are listed here, as procedures may have changed.

Even if you habitually compile things from source, I'd advise you to go for the binary versions where I've indicated, unless you really have no use for your hair. Most of them are not set up for `crosscompiling' on an a.out-based system, and you are probably lining yourself up for major grief if you try.

Absolute essentials

Others

These are other libraries and files which aren't strictly essential, but that you might want to get anyway. This list contains only packages that need to be upgraded to work in an ELF-useful fashion. Later in this document is another list of programs which will continue to work but which you'll have to tweak/upgrade if you want to recompile them in ELF. If your net access involves high-latency links (like, say, a five-minute walk with a box of floppy disks), skip forwards and check that one too before you set out :-)

2.4 Rearranging your filesystem

Sooo... Note that in all that follows, when I say `remove' I naturally mean `backup then remove' :-). Take a deep breath ...

  1. The essentials --- binary installation

  2. Make the new directories that you will move a.out things to
    mkdir -p /usr/i486-linuxaout/bin
    mkdir -p /usr/i486-linuxaout/include
    mkdir -p /usr/i486-linuxaout/lib
    mkdir /lib-aout
    
  3. Untar the dynamic linker package ld.so-1.7.14 in the directory you usually put source code, then read through the ld.so-1.7.14/instldso.sh script just unpacked. If you have a really standard system, run it by doing sh instldso.sh, but if you have anything at all unusual then do the install by hand instead. `Anything at all unusual' includes
  4. Edit /etc/ld.so.conf to add the new directory /usr/i486-linuxaout/lib (and /lib-aout if you're going to need one). Then rerun /sbin/ldconfig -v to check that it is picking up the new directories.
  5. Move all the a.out libraries in /usr/lib and /usr/*/lib to /usr/i486-linuxaout/lib. Note, I said `libraries' not `everything'. That's files matching the specification lib*.so* , lib*.sa*, or lib*.a. Don't start moving /usr/lib/gcc-lib or anything silly like that around.
  6. Now look at /lib. Leave intact libc.so*, libm.so*, and libdl.so*. If you have symlinks to X libraries (libX*.so.3*) leave them there too --- XView and some other packages may require them. Leave ld.so*, ld-linux.so* and any other files starting with ld. As for the remaining libraries (if there are any others): if you have /usr on the root partition, put them in /usr/i486-linuxaout/lib. If you have /usr mounted separately, put them in /lib-aout. Now run ldconfig -v
  7. Remove the directory /usr/lib/ldscripts if it's there, in preparation for installing the binutils (which will recreate it)
  8. Remove any copies of ld and as (except for ld86 and as86) that you can find in /usr/bin.
  9. You need to clean up your /usr/include hierarchy. On an average system, some of the files in here are `core' functionality and come with libc, while others are from other packages that you or your distribution builder have installed. Given this mess, I suggest you remake it from scratch; rename it to /usr/include.old, then unpack libc-5.2.18.bin.tar.gz by untarring it from the root directory.
  10. Install the binutils package. tar -xvzf binutils-2.6.0.12.bin.tar.gz -C / is one perfectly good way to do this.
  11. The gcc package expects to be untarred from root. It installs some files in /usr/bin and lots more in /usr/lib/gcc-lib/i486-linux/2.7.2 and /usr/lib/gcc-lib/i486-linuxaout/2.7.2. Use
    $ tar ztf gcc-2.7.2.bin.tar.gz
    
    to see what's in it, backup anything that it overwrites that you feel you may want to keep (for example, if you have Gnu ADA installed you will probably want to keep /usr/bin/gcc), then just do
    # tar -zxf gcc-2.7.2.bin.tar.gz -C /
    
    At this point, you should be able to run gcc -v and compile test programs. Try
    $ gcc -v
    Reading specs from /usr/lib/gcc-lib/i486-linux/2.7.2/specs
    gcc version 2.7.2
    $ gcc -v -b i486-linuxaout
    Reading specs from /usr/lib/gcc-lib/i486-linuxaout/2.7.2/specs
    gcc version 2.7.2
    $ ld -V
    ld version 2.6 (with BFD 2.6.0.2)
      Supported emulations:
       elf_i386 
       i386linux 
       i386coff 
    
    followed of course by the traditional ``Hello, world'' program. Try it with gcc and with gcc -b i486-linuxaout to check that both the a.out and ELF compilers are set up correctly. Finished? Not quite. You still have all the `non-core' libraries to install, and a fair amount of mucking about with symlinks. Onwards...

    Symlinks

  12. Some programs (notably various X programs) use /lib/cpp, which under Linux is generally a link to /usr/lib/gcc-lib/i486-linux/version/cpp. As the preceding step probably wiped out whatever version of cpp it was pointing to, you'll need to recreate the link:
    # cd /lib
    # ln -s /usr/lib/gcc-lib/i486-linux/2.7.2/cpp .
    
  13. When you moved /usr/include to /usr/include.old, you lost the symlinks into the kernel sources. Run
    # cd /usr/include
    # ln -s ../src/linux/include/linux .
    # ln -s ../src/linux/include/asm .
    
    (assuming you have kernel source in /usr/src/linux; if not, season to taste)
  14. The FSSTND people have once again justified their keep by moving the utmp and wtmp files from /var/adm to /var/run and /var/log respectively. You'll need to add some links dependent on where they currently live, and you may need to make the /var/log and /var/adm directories too. I reproduce below the ls -l output of appropriate bits on my system:
    $ ls -ld /var/adm /var/log /var/run /var/log/*tmp /var/run/*tmp
    lrwxrwxrwx   1 root     root            3 May 24 05:53 /var/adm -> log/
    drwxr-xr-x   9 root     root         1024 Aug 13 23:17 /var/log/
    lrwxrwxrwx   1 root     root           11 Aug 13 23:17 /var/log/utmp -> ../run/utmp
    -rw-r--r--   1 root     root       451472 Aug 13 23:00 /var/log/wtmp
    drwxr-xr-x   2 root     root         1024 Aug 13 23:17 /var/run/
    -rw-r--r--   1 root     root          448 Aug 13 23:00 /var/run/utmp
    
    Check the FSSTND (from LDP archives such as ftp://sunsite.unc.edu/pub/Linux/docs/fsstnd/) for the full story.

    Rejoice!

    By this time you should have a (more or less) fully functioning ELF development system. Stand back and celebrate quietly for a few minutes.

    Essential source code packages

  15. ncurses installation is a fairly long job, though most of of the time can be spent reading Usenet while it builds. After unpacking the tar file, read the INSTALL file pretending that you are `a Linux ...] distribution integrator or packager'; that is, you probably want to be configuring it with a command like
    $ ./configure --with-normal --with-shared --disable-termcap --enable-overwrite --prefix=/usr
    
    Take heed also of the comments about the default terminal type; in 1.3 and 2.0 kernels this is set to linux at boot time, but you may find that you need to edit /etc/inittab to avoid having it set back to console by getty. If you do not have /usr/lib/terminfo on the root disk you will have to fiddle with the `fallback' support in ncurses. This is documented in the INSTALL file mentioned above, and is simple but tedious (due to the necessity of building the library twice). If you're happy with having linux and vt100 as fallbacks, there is a ready-prepared fallback.c at ftp://ftp.uk.linux.org/pub/Linux/libc/non-core/fallback.c which you can copy over the existing one. After you have installed ncurses, you'll have to get messy in /usr/lib --- it does some non-optimal things that are simplest to clear up by hand. Note the weird discrepancy between the version numbers; this is ugly but not actually detrimental to human health.
    1. /usr/lib/libncurses.so.1.9.9e should be moved to /lib so that curses programs which run in single-user mode will continue to do so. If you have /usr/lib on the root partition, this is unnecessary but will do no harm.
    2. In /lib, make a link to libncurses.so.1.9.9e called libncurses.so.3.0.
    3. You also need links /usr/lib/libncurses.so, /usr/lib/libcurses.so and /usr/lib/libtermcap.so which should all point to /lib/libncurses.so.3.0.
    In brief for the hard of thinking, that little lot was
    # cd /lib
    # mv /usr/lib/libncurses.so.1.9.9e .
    # ln -s libncurses.so.1.9.9e libncurses.so.3.0 
    # cd /usr/lib
    # ln -s /lib/libncurses.so.3.0 libncurses.so
    # ln -s /lib/libncurses.so.3.0 libcurses.so
    # ln -s /lib/libncurses.so.3.0 libtermcap.so
    
  16. gdbm installation. Unpack the source code in a source code directory, apply gdbm.patch, and look over the README and INSTALL files. The build process should go something like:
    $ tar zxf gdbm-1.7.3.tar.gz
    $ patch -p0 < gdbm.patch
    $ cd gdbm-1.7.3
    $ ./configure --prefix=/usr
    $ make 
    $ make progs
    $ su
    # make install
    # make install-compat
    # cd /usr/lib
    # ln -s libgdbm.so.1 libgdbm.so
    # ln -s libgdbm.so.1 libgdbm.so.2
    # ldconfig
    
    The last step is for backward-compatibility; some current distributions use libgdbm.so.2 which is exactly the same code as libgdbm.so.1, but misnumbered for historical reasons.

    Optional source code packages. In general, you can just install these according to their instructions, so I won't repeat them. There are two exceptions, though:

  17. If you want the GNU-ish termcap (strictly speaking, optional; in practice, necessary to use XFree86 binaries) it also needs to be built from source, but shouldn't require anything more complex than
  18. $ tar zxf termcap-2.0.8.tar.gz
    $ cd termcap-2.0.8
    $ make
    $ su
    # cp libtermcap.so.2.0.8 /usr/lib
    # ldconfig
    

    I recommend that you don't make install, as this would overwrite bits of the ncurses installation. If you need to actually compile things against this library, as opposed to just running binaries that were made with it, think about putting the header files and static libraries somewhere nonstandard, and using -I and -L flags when you compile the said things. The vagueness of this description should make it plain that continued use of termcap is `discouraged' unless you have a good reason.

  19. For libdb, it goes something like:
  20. $ tar zxf db.1.85.tar.gz
    $ patch -p0 <db.patch
    $ cd db.1.85/PORT/linux
    $ make
    $ su
    # mkdir /usr/include/db
    # ldconfig
    # cp libdb.so.1.85.3 /usr/lib ; ( cd /usr/lib && ln -s libdb.so.1 libdb.so )
    # cp ../../include/*.h /usr/include/db
    

    Note that

2.5 What it should look like (outline directory structure)

This is a deliberately vague guide to what the files you have just installed are. It may be useful for troubleshooting or deciding what to delete.

/lib

/usr/lib

/usr/lib/ldscripts

/usr/i486-linux/bin

/usr/i486-linuxaout/bin

/usr/i486-linux/lib

/usr/i486-linuxaout/lib

/usr/lib/gcc-lib/i486-linux/2.7.2

/usr/lib/gcc-lib/i486-linuxaout/2.7.2

2.6 Co}mon errors --- Don't Panic!

(in large friendly letters)

You moved the wrong thing and now nothing runs

You still have a shell running, though, and with a little ingenuity you can do an awful lot with shell builtins. Remember that echo * is an acceptable substitute for ls, and echo >>filename can be used to add lines to a file. Also, don't forget that ldconfig is linked static. If you moved, say, libc.so.4 to /lib-aout mistakenly, you can do echo "lib-aout" >>/etc/ld.so.conf ; ldconfig -v/ and be back up again. If you moved /lib/ld.so you may be able to do sln /silly/place/ld.so /lib/ld.so, if you have a statically linked ln, and probably be back up again.

bad address

on attempting to run anything ELF. You're using kernel 1.3.x, where x<3. Don't. They're probably the buggiest Linux kernels on the planet anyway. Upgrade to 2.0 or downgrade to 1.2.13. Some people also report kernel panics in similar circumstances; I haven't investigated, chiefly as I can think of no reason for wanting or needing to run development kernels and not keeping up with the releases.

gcc: installation problem, cannot exec something: No such file or directory

when attempting to do a.out compilations (something is usually one of cpp or cc1). Either it's right, or alternatively you typed

$ gcc -b -i486-linuxaout

when you should have typed

$ gcc -b i486-linuxaout

Note that the `i486' does not start with a dash.

make: *** No targets specified and no makefile found. Stop.

indicates that you haven't patched and recompiled make, or that you still have an old version of it elsewhere on the system.

no such file or directory: /usr/bin/gcc

(or any other file that you try to run) when you know there is such a file. This usually means that the ELF dynamic loader /lib/ld-linux.so.1 is not installed, or is unreadable for some reason. You should have installed it at around step 2 previously.

not a ZMAGIC file, skipping

from ldconfig. You have an old version of the ld.so package, so get a recent one. Again, see step 2 of the installation.

_setutent: Can't open utmp file

This message is often seen in multiples of three when you start an xterm. Go and read the FSSTND tirade near the end of the installation procedure.


Next Previous Contents