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. SUPPORTED BINARY FORMATS * A.OUT (using standard Linux loader) * ELF (using standard Linux loader) * COFF * XOUT SUPPORTED OS EMULATIONS * 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. SUPPORTED SUBSYSTEM EMULATIONS * SYSV IPC * /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*. LIMITATIONS 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 unlikely. 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. MAILING LIST 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 this. INSTALLATION 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 :-(. UTILITIES 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. LIBRARIES 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. BUG HUNTING 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! LIMITATIONS 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. LOCAL X CONNECTIONS 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... REFERENCES 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 1-614-755-4151. 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...