iBCS Emulation for Linux

The Intel Binary Compatibility Specification, or iBCS, specifies the
interfaces between application programs and the surrounding operating
system environment for i386 based systems. There are however several
flavours of iBCS in use - SVR4, SVR3 plus several vendor specific
extensions to SVR3 which are slightly different and incompatible. The
iBCS emulator for Linux supports all flavours known so far.


	* A.OUT (using standard Linux loader)
	* ELF	(using standard Linux loader)


	* i386 BSD (386BSD, FreeBSD, NetBSD, BSDI/386) - very alpha.
	* SVR4 (Interactive, Unixware, USL, Dell etc.)
	* SVR3 generic
	* SCO (SVR3 with extensions for symlinks and long filenames)
	* Wyse V/386 (SVR3 with extensions for symlinks)
	* Xenix V/386 (386 small model binaries only)
	* Xenix 286

Unrecognised binaries will default to the Linux personality for ELF or
the SVR3 personality for COFF binaries. If there are non-standard
extensions which require handling a new personality may need creating
in the emulator.

  Recognition of BSD binaries requires a patch to the standard Linux
kernel loader in linux/fs/exec.c. It is difficult to differentiate
between Linux and BSD binaries. The patch is not elegant. Sorry.



	* /dev/socksys socket interface as used by the Lachman STREAMS
	  based networking implementation.

	* Wyse V/386 system call socket interface.

	* /dev/spx STREAMS device for connections to local X server 0 *only*.


Unix variants with non-standard extensions which are not SVr4, SCO or Wyse
will not be recognised and may fail unexpectedly. A new personality may
need to be built.

The recognition of SCO and Wyse binaries is dependent on comment strings
embedded in the binary at compile time. If these strings are missing or
not as expected the binary will not be recognised correctly and may
fail unexpectedly. It is also possible that binaries from other systems
may be misrecognised although given the strings used this should be

Some Xenix functions are unimplemented, in particular Xenix semaphores.

The SCO support for connections to a local X server only extends to :0.0.
If necessary you can connect to other servers by forcing the connection via
the TCP/IP loopback interface. This is done by specifying the DISPLAY
environment variable as localhost:0.0.

SVr4 local connections are made using the same named pipes that linux
uses.  SVr4 networking should be working if you use the libnsl.so and
libsocket.so shared libraries that come with the libc_s package.

There is no support for TLI networking. If anyone can think of a good
reason why TLI is necessary it *may* be possible to do something...

There is no STREAMS support. Programs that rely on STREAMS features and
functionality will not work.

Programs, applications or packages which require modules or device drivers
to be linked in to the kernel will not work. Linux is *not* based on SYSV
code and does not have SYSV internals. The driver would need rewriting for
use under Linux.


The mail list for this project is located at linux-ibcs2@vger.rutgers.edu.
To subscribe send mail to majordomo@vger.rutgers.edu with the text
"subscribe linux-ibcs2" in the body.

An older mailing list is at linux-activists@joker.cs.hut.fi. Avoid using


1. Extract the archive (you have already done this of course). It doesn't
   matter where you put this source. You will need the "insmod" program
   from the modutils archive to load the compiled emulator module
   (available on all major Linux archive sites).

2. There may be optional patches - check the options in the Makefile and
   the patches in the Patches directory. If you are using a non-current
   1.3 kernel you should upgrade it. The 1.3 series is a development kernel
   and liable to frequent changes. Non-current releases of 1.3 will *not*
   be supported!

	# patch -d /usr/src/linux -p1 < Patches/

3. Do a 'make' in the ibcs directory. A 'make install' will then
   install the iBCS module in /usr/lib/modules/iBCS and the x286emul
   Xenix 286 emulation overlay in /usr/lib/x286emul.

4. The interfaces to some subsystems occur at the device layer and thus
   you need to create some device files in order to use them. The
   current (2.1?) MAKEDEV knows about some of these at least and they
   can be created using:

	  # cd /dev
	  # MAKEDEV ibcs2

   If you don't have a recent MAKEDEV you need to create the device
   files by hand. Note that if you do this you may wish to check the
   major number used by socksys in /proc/devices. iBCS can be built
   to auto-allocate the next available major number - MAKEDEV checks
   /proc/devices automatically.

	* /dev/socksys and /dev/nfsd - interface for SVr3 STREAMS based
	  TCP/IP applications

	  # mknod /dev/socksys c 30 0
	  # ln -s /dev/socksys /dev/nfsd

	* /dev/X0R - server side of SVR3 local X interface
	  (see comments in Doc/Local-X)

	  # ln -s /dev/null /dev/X0R

	* /dev/spx - client side of SVR3 local X interface
	  (see comments in Doc/Local-X)

	  # mknod /dev/spx c 30 1

	* /dev/inet/* - transport provider access points for STREAMS/XTI
	  services. Note that the minor number encodes the address family
	  (AF_INET, AF_UNIX etc.) in the high 4 bits and a protocol
	  indicator in the low 4 bits. The protocol indicator is *not* the
	  actual protocol code - the minor number isn't big enough to
	  encode everything we need. The open routine in socksys.c maps
	  the protocol indicator to the protocol code and infers the socket
	  type from the protocol. Don't worry about it. Just do the following:

	  # mknod /dev/inet/ip c 30 32
	  # mknod /dev/inet/icmp c 30 33
	  # mknod /dev/inet/ggp c 30 34
	  # mknod /dev/inet/ipip c 30 35
	  # mknod /dev/inet/tcp c 30 36
	  # mknod /dev/inet/egp c 30 37
	  # mknod /dev/inet/pup c 30 38
	  # mknod /dev/inet/udp c 30 39
	  # mknod /dev/inet/idp c 30 40
	  # mknod /dev/inet/rawip c 30 41

	  Note that only ip, icmp, tcp and udp are strictly required. The
	  others are there for completeness.

	  You should also have arp and rip which are not strictly protocols
	  in their own right as far as we are concerned. The necessary
	  functionality should be accessible from a udp connection.

	  # cd /dev/inet
	  # ln -s udp arp
	  # ln -s udp rip

	* SVR4 wants the above transport providers in /dev not /dev/inet
	  so add some links.

	  # cd /dev/inet
	  # for i in *
	  > do
	  >   ln -s /dev/inet/$i /dev/$i
	  > done

5. Load the iBCS emulator using 'insmod /usr/lib/modules/iBCS'.

9. Run the SVr4, SCO or iBCS2 programs. Pay attention to the COMPAT
   file, the HINTS file and any patches that may be in PROD.Patches.
   Just because they are commercial doesn't make them perfect :-(.


The emulator has the ability to trace the events which it processes. The
program to enable the tracing function is contained in the Tools directory.

To make the trace utility, go to the Tools directory and do a make.

Run 'trace' with no arguments to get a list of capabilities. Full tracing
is enabled using 'trace all'. This is extremely verbose - you probably
want to kill syslogd and use 'tail -f' to dump /proc/kmsg directly to
a file as quickly as possible if you enable this.

If you have no intention of ever using the trace facilities (and will
never complain that something doesn't work) you can remove the IBCS_TRACE
option and recompile the emulator without the tracing facilities. This
makes the emulator about a third smaller but ensures that there is no
way for you to find out if program failures are directly due to faults
in the emulator.


The shared libraries are on the list of ToDo. The libc file is being
developed by Eric Youndale and Al Longyear. Precompiled versions of
this library should be available from the same ftp site as the iBCS2
emnulator.  Note that you can also use the shared libraries from your
iBCS system under linux, but is to include the shared library from
your iBCS system on Linux. It is your responsibility to check whether
your license allows you to do this whether directly or via NFS.

For SVr4 binaries, precompiled libraries build from this library
should be available that will work for many applications.  Note
that the precompiled libraries are closer in flavor to UnixWare/Dell
than to Solaris/x86, although in theory both should be supportable
by the same libraries.

The SCO shared libraries should be stored in the directory /shlib. This
may be a symlink elsewhere.

The libraries are:

	* libc_s   - standard C runtime library
	* libnsl_s - network services library
	* libx11_s - X windows library

Additional libraries may be available on your system. They may be called
SCOlibc_s or some similar name. Those libraries will not be available for
Linux. They are specific to the SCO system. The three libraries listed
above are the only ones which are specified in iBCS specification.

SCO has the following shared libraries:

	* libc_s	- standard C runtime library
	* libnsl_s	- SCO version of network services
	* libnsl_s.att	- AT&T version of network services
	* libsc_s	- console functions???
	* protlib_s	- SCO specific security functions
	* libX11R5_s	- X windows libraries
	* libXR4sco_s
	* libXtXm1.2_s
	* libXtXm114_s
	* libXtXm_s

On SVr4 machines, the shared libraries tend to be stored in /usr/lib,
and are called libc.so.1, libsocket.so, and libnsl.so.  You can use
environment variables to specify alternate locations for these files.
The SVr4 versions of these libraries can be built on either a SVr4
machine, or on a linux machine using the ELF compiler, assembler and
linker that have been developed for native linux ELF support.  The
SVr4 version of the linux dynamic loader expects to locate the SVr4
versions of the shared libraries in the directory /usr/i486-sysv4/lib
so as to minimize the confusion between native linux ELF libraries and
the SVr4 ELF shared libraries.  The SVr4 X11 libraries are not part of
this package, but precompiled libraries for X11 can be obtained from
the binary sites for XFree86.

As with the COFF shared libraries, you will be able to use the
libc.so.1 from your SVr4 machine on your linux machine, and it should
work.  Once again, it is your responsibility to check whether your
licence allows this.  Do not even think about trying to use the
libsocket.so or libnsl.so shared libraries from a SVr4 machine on a
linux box - they assume that the kernel supports STREAMS, and until
Linux supports STREAMS, you will just be wasting your time.  The
libc_s distribution that we have prepared also contains a
libsocket.so/libnsl.so which contain stubs for the socket-based
functions that should provide compile networking support.

 The source for the libc_s library is in the development directory on
tsx-11.mit.edu. Join the IBCS2 mailing list if you wish to work on
unreleased development code.


If you find a program which produces warnings about unsupported syscalls
or ioctls please look at available header files and/or man pages and
try and identify what should be happening. If we know what the program
expects to happen we can emulate it.

If you find a program which runs but crashes at some point then try and
reproduce the problem. Once you can crash it at will you can generate
a trace of the relevant section. Run the program and bring it to a point
a little before it crashes then enable tracing in the emulator and dump
the trace to a file by running (on a different VT or xterm):

	# killall syslogd syslogk klogd
	# dmesg -c > /dev/null
	# tail -f /proc/kmsg > /tmp/log &
	# .../ibcs/Tools/trace all

Then do whatever it is that causes the crash, disable the emulator tracing
and kill the tail:

	# .../ibcs/Tools/trace off
	# killall tail

and examine the log.

If the program is trying to access a device that doesn't exist and whose
intended behaviour is not readily apparent (not all devices are devices,
take a look at /dev/socksys which implements the socket system calls
behind ioctls) you may wish to use the devtrace module. Firstly, if
you aren't using a recent (1.1.45+?) kernel you will need to edit the
file devtrace.c and define a fixed major number. Build the module
using 'make devtrace' and load it with insmod. If you left the major
number as zero look up the allocated number in /proc/devices then
create whatever device nodes your program is trying to access. The
devtrace module simply writes kernel syslog messages for all operations
performed on it and pretends that everything succeeds. This will
cause your program to die horribly but should leave you with enough
information to find out what was expected of the real device.

If you can fix the problem do so and post the fix to the IBCS2 mailing
list, otherwise post the *relevant* details you have - parts of the log
file, ioctl details, syscall details etc. Remember, it's better to post
too little initially and then post further details when asked than it
is to post too much and annoy people who may be able to help!


Until the COFF network services shared library is implemented, the
network programs probably will not work with COFF binaries that are
linked to the shared libraries. There is some network code in the
emulator.  This allows the Wyse iBCS system to work with the
network. If you wish to try other systems, then please do so. A lot of
work has been done in the network area as far as the emulator is
concerned. Please let us know about the results.

SVr4 binaries using the ELF emulation libraries tap into the Wyse
TCP/IP code, and should be completely functional WRT the network.

Until the COFF X library is implemented, COFF X windows applications
_probably_will_ _not_work_ on this system. Mike Jagdis has reported
that he can get the X version of WordPerfect to work on his system. It
does not use shared libraries. There is hope. :-)

For SVr4, you can obtain the X11 shared libraries from the binary
distribution sites of XFree86.


The local X interface is simplistic. It assumes only one local X server
exists and assumes that the pathname of the Unix domain socket for
local connections is always /tmp/.X11-unix/X0. This is true if you
are using the first X display. It may not be true if you have started
multiple X displays.

  The SCO code opens both /dev/X0R and /dev/spx, writes a single byte
to /dev/X0R, reads a message from /dev/X0R with getmsg then writes this
message to /dev/spx with putmsg and closes /dev/X0R. This establishes
the /dev/spx file descriptor as a connection to the X server listening
on /dev/X0R.

  We ignore all activity on the /dev/X0R device (hence it is a link to
/dev/null), getmsg and putmsg are stubbed so don't do anything and opens
on the /dev/spx simply replace the open inode with a socket connected
to the X server's Unix domain socket.

  At some point in the future we may implement a simple minded /dev/X*
driver that returns some form of id via the getmsg which can then be
passed to /dev/spx with putmsg and which will allow /dev/spx to connect
to the relevant X server. This will only happen if someone actually
*needs* multiple local X servers...


The Intel Binary Compatibility Specification, version 2 is described in
the "McGraw Hill book".

	Intel Binary Compatibility Specification
		McGraw-Hill, Inc.
		1221 Avenue of the Americas
		New York, NY 10020
		ISBN 0-07-031219-2

The McGraw Hill order desk can be reached on 1-800-722-4726 or

Vendor specific extensions were determined through a combination of
header files, man pages, manuals and the behaviour of existing programs.
To the best of my knowledge no developer of the iBCS emulator has ever
had access to controlled Unix source - never mind used it as a reference.
To be honest it probably wouldn't have helped...