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:
ld.so
.
These would all cease working if their libraries were moved from under
them. Thus, libc.so*
and libm.so*
must stay where they are
in /lib
, and the ELF versions have had their major numbers
upgraded so that they do not overwrite the a.out ones. Old X
libraries (prior to version 6) are best left where they are also,
although newer ones (libX*so.6
) must be moved. Moving the old
ones will apparently break xview programs, and not moving the new ones
will cause them to be overwritten when you install ELF X libraries.
If you have non-ld.so programs that require libraries other than the
above (if you know which programs they are, you can run ldd on them to
find out which libraries they need before breaking them) you have
essentially two options. One, you can extract the ELF library tar
files into a temporary directory, check whether your precious library
would be overwritten, and if so, move the ELF version of the library
into, say, /usr/i486-linux/lib
instead of /lib
.
Make sure your ld.so.conf
has /usr/i486-linux/lib
in it,
then run ldconfig
and think no more on't. Two, you can recompile
or acquire a newer copy of the offending program. This might not be a
bad idea, if possible.
/usr
and /
on different
partitions, any libraries that you move from /lib
must end up
somewhere else on the root disk, not on /usr
. I used
/lib-aout
in the instructions that follow.
mv
, ln
, and maybe other file manipulation commands
(though in fact I think you can do everything else you actually
need to with shell builtins) may help you out of any awkward
situations you could end up in.
/lib/elf
(usually
libc.so.4
and co). Applications that you built using these
should be rebuilt, then the directory removed. There is no need for a
/lib/elf
directory!
/sbin/
something and you don't have a /sbin
directory, you'll probably find the program referred to in
/bin
or /etc/
. It is especially important to check
this when you install new programs; if you have /etc
nearer
the front of the search path than /sbin
you'll get odd
failures due to running the old versions when you weren't expecting
to.
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.
ld.so-1.7.14.tar.gz
--- the new dynamic linker. Contains
both source and binaries. Note that forthcoming versions of this will
require kernel ELF support even for a.out binaries; if you get 1.8.1
or later instead of the version listed, make sure that the kernel
you're running was compiled with ELF support before you install
this.
libc-5.3.12.bin.tar.gz
--- the ELF shared images for the C
and maths libraries, plus the corresponding static libraries and the
include files needed to compile programs with them. Source is also
available if you like it, but it takes ages to compile, and probably
won't at all unless you already have an ELF system.
gcc-2.7.2.bin.tar.gz
--- the ELF C compiler package, which
also includes an a.out C compiler which understands the new directory
layout. If you want to build gcc yourself (which you'll probably find
is simpler when you're already running ELF), you're recommended to
apply gcc-2.7.2-linux.diff.gz
to the GNU sources first.
binutils-2.6.0.12.bin.tar.gz
--- the GNU binary utilities
patched for Linux. These are programs such as gas
, ld
,
strings
and so on, most of which are required to make the C
compiler go. Note that the vanilla GNU binutils (e.g. from
prep.ai.mit.edu
) are not an acceptable substitute; if you really
want to compile this yourself you'll need to use the patched-for-Linux
binutils-2.6.0.12.tar.gz
package instead of the GNU one.
ncurses-1.9.9e.tar.gz
--- this is an SVR4-compatible
curses library, which is henceforward deemed to be the `standard
curses library' for Linux. The source is available from GNU sites
such as
ftp://prep.ai.mit.edu/gnu/ and also from
ftp://ftp.netcom.com/pub/zm/zmbenhal, and there is a binary
package on tsx-11
. By the time you get to install this you will
have a fully functional ELF development system, so I recommend the
source package if you have any kind of compilation horsepower. That
may just be me, though.
gdbm-1.7.3.tar.gz
is a set of database routines that use
extensible hashing and work similarly to the standard UNIX dbm and
ndbm routines. The source is available from GNU sites such as
ftp://prep.ai.mit.edu/gnu/; you also need a patch
ftp://ftp.uk.linux.org/pub/Linux/libc/non-core/gdbm.patch to
make shared libraries out of it. That patch also fixes a couple of
other things (a one-character typo in the Makefile and a
predisposition to use the wrong kind of file locking).
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 :-)
libc.so-4.7.6
. This is listed as `optional' because your
existing a.out libraries of whatever vintage will continue to work
fine with your existing binaries. You might find that you need this
if you plan to continue developing in a.out for whatever reason.
libcurses.so.1
, this is the old BSD curses library. They're
probably quite rare, which is fortunate as I can't presently find a
(source code) copy of the library. It's probably best to recompile
programs like this to use ncurses; if this is not an option, there is
a binary libcurses.so
in the libc-5.0.9.bin.tar.gz
on
tsx-11
mirrors.
libdb
database
routines. The source can be had from
ftp://ftp.cs.berkeley.edu/ucb/4bsd/db.1.85.tar.gz/, and the patch
for Linux shared libraries is
ftp://ftp.uk.linux.org/pub/Linux/libc/non-core/db.patch
gcc
package comes with
g++
, but you'll also need libg++-2.7.1.4.bin.tar.gz
to
compile any useful C++ software. I don't use C++ myself, but I
understand that it is nontrivial to build this from source, hence the
binary recommendation.
gdb
is a legitimate example. If you intend to debug
shared libraries and you think that gdb is getting confused about the
ones that it's linked with itself, you probably want a statically
linked copy of it; in this case, you'll find that a real termcap is a
lot smaller than the termcap-compatible routines in ncurses.
termcap-2.0.8.tar.gz
is available from tsx-11
. This is
not GNU Termcap, but it is completely compatible (the differences
are in the error checking, apparently). This is a source code package.
/dev/zero
, which causes some versions of
ld-linux.so.1
to break. Find a new version at
ftp://sunsite.unc.edu/pub/Linux/system/Admin/MAKEDEV-C-1.5.tar.gz
or
ftp://sunsite.unc.edu/pub/Linux/system/Admin/MAKEDEV-2.2.tar.gz.
modules-2.0.0
. If you use modules, the upgrade to
binutils which you're shortly about to perform will break all versions
of the modules utilities older than 1.3.69. New modules utilities can
be had from
http://www.pi.se/blox/.
ftp
to ftp.xfree86.org
, read the `too many users' message
that you are almost guaranteed to get, and pick the closest mirror
site network-wise to you. Once you have the contents of the
common
and elf
directories, you must edit
/usr/X11R6/lib/X11/config/linux.cf
to change the lines saying
#define LinuxElfDefault NO
#define UseElfFormat NO
to say YES
instead. Otherwise an xpm build will attempt to do
odd stuff with jumpas
and its associated relics of the past.
Note that XFree86 binaries currently require an ELF shared termcap
library (libtermcap.so.2
) to be installed.
If you use Motif, you may also need to contact your vendor, to
investigate whether they will supply ELF Motif libraries. I don't use
it; I can't help here.
Documentation/Changes
file
that comes in the kernel source, to find out what else you'll need.
Sooo... Note that in all that follows, when I say `remove' I naturally mean `backup then remove' :-). Take a deep breath ...
The essentials --- binary installation
mkdir -p /usr/i486-linuxaout/bin
mkdir -p /usr/i486-linuxaout/include
mkdir -p /usr/i486-linuxaout/lib
mkdir /lib-aout
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
$VERSION
, which seems to confuse instldso.sh
)
/lib/elf
to /lib
(which
you shouldn't need, but that's scant consolation when you're looking
for the rescue disk)
/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.
/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.
/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
/usr/lib/ldscripts
if it's there,
in preparation for installing the binutils (which will recreate it)
ld
and as
(except for ld86
and as86
) that
you can find in /usr/bin
.
/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.
tar -xvzf
binutils-2.6.0.12.bin.tar.gz -C /
is one perfectly good way to
do this.
/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
/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 .
/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)
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
INSTALL
file pretending that you
are `a Linux
$ ./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.
/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.
/lib
, make a link to libncurses.so.1.9.9e
called
libncurses.so.3.0
.
/usr/lib/libncurses.so
,
/usr/lib/libcurses.so
and /usr/lib/libtermcap.so
which
should all point to /lib/libncurses.so.3.0
.
# 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
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:
$ 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.
libdb
, it goes something like:
$ 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
PORT/linux/OTHER_PATCHES
, because it's
subsumed by this patch
/usr/include
--- they conflict with the ones that gdbm uses. To
compile programs that want libdb
you must add
-I/usr/include/db
to the C compiler's command line.
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
ld.so
(a.out) and ld-linux.so.1
(ELF).
Either of these may be symlinks, but make sure that the files they
point to do exist.
libc.so.4
, libm.so.4
(a.out)
These are symlinks, but check that they point to real files.
libc.so.5
, libm.so.5
,
libdl.so.1
,libncurses.so.1
,libtermcap.so.2
, (ELF).
Again, these are symlinks. Check the files that they point to.
/usr/lib
libbfd.so*
,libdb.so*
, libgdbm.so*
, ELF shared
libraries.
/lib
or /usr/lib
,
there should be a symlink in here. The link's name should be the real
filename, minus the version number. For example, for libc
,
lrwxrwxrwx 1 root root 14 May 2 20:09 /lib/libc.so.5 -> libc.so.5.3.12
-rwxr-xr-x 1 bin bin 583795 Apr 25 06:15 /lib/libc.so.5.3.12
lrwxrwxrwx 1 root root 12 Oct 27 1995 /usr/lib/libc.so -> /lib/libc.so.5
These links are used by ld
at link time.
libbsd.a
, libgmon.a
, libmcheck.a
,
libmcheck.a
and one lib*.a
file for every ELF shared library
in /lib
and /usr/lib
. ELF static libraries. The
ones that duplicate shared libraries may not be tremendously useful
for most people --- when using ELF, you can use the gcc -g
switch
with shared libraries, so there's not much reason to compile static
any longer. You will need to keep them if you actually want to
debug the libraries themselves.
crt0.o
, gcrt0.o
. a.out `start of program' files; one
of these is linked as the first file in every a.out program you
compile, unless you take steps to avoid it.
crt1.o
, crtbegin.o
, crtbeginS.o
, crtend.o
,
crtendS.o
, crti.o
, crtn.o
, gcrt1.o
. ELF startup
files. These do similar things to *crt0.o
above for ELF programs.
/usr/lib/ldscripts
ld
live, as the name
suggests. It should look like
$ ls /usr/lib/ldscripts/
elf_i386.x elf_i386.xs i386coff.xn i386linux.xbn
elf_i386.xbn elf_i386.xu i386coff.xr i386linux.xn
elf_i386.xn i386coff.x i386coff.xu i386linux.xr
elf_i386.xr i386coff.xbn i386linux.x i386linux.xu
/usr/i486-linux/bin
ar
, as
, gasp
, ld
, nm
, ranlib
,
strip
. These are all actually symlinks to the real binutils in
/usr/bin
/usr/i486-linuxaout/bin
as
--- the a.out assembler, and gasp
, its macro preprocessor
ar
, ld
, nm
, ranlib
, strip
--- symlinks
to the real binutils in /usr/bin
/usr/i486-linux/lib
ldscripts
is a symlink to /usr/lib/ldscripts
./usr/i486-linuxaout/lib
lib*.so*
. a.out shared library images. Needed to run
a.out programs
lib*.sa
. a.out shared library stubs. Needed to compile
a.out programs that use shared libraries. If you don't intend to, you
can safely remove these.
lib*.a
. a.out static libraries. Needed to compile static
a.out programs (eg when compiling with -g
). Again, you can
delete them if you don't intend to do this.
ldscripts
is a symbolic link to /usr/lib/ldscripts
/usr/lib/gcc-lib/i486-linux/2.7.2
/usr/lib/gcc-lib/i486-linuxaout/2.7.2
(in large friendly letters)
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.