Installation instructions should be included with whatever distribution
you pick.
Seriously, it works by remapping system calls on the fly. As it turns
out, there's not much difference between Linux and iBCS2
binaries. The main difference is the way in which system
calls are handled. In Linux, an "int $0x80" instruction is
used, which jumps to the system-call-handling portion of
the Linux kernel. On other systems, "int $0x80" usually causes
a SIGSEGV signal. Lxrun intercepts these signals and calls
the native equivalent of the system call that the Linux
program attempted. The result is that the Linux binary
can be run (with the help of lxrun) with a small (usually
negligible) performance penalty. All this is accomplished
without modifying the kernel or the Linux binary.
System calls are used for I/O, displaying
things on the screen, accessing the network, etc. System calls
are not used during computation. This means that
computation-intensive applications (such as compilers,
image processors, etc.) will show the least difference in
performance. As for more I/O-driven applications, consider this: The time
it takes to access data on a hard drive or to transfer data over
typical networks is usually measured in milliseconds. Are you
really going to notice a few extra microseconds of
system call translation? No... The time it takes for lxrun
to remap a system call is effectively "lost in the noise";
it most often represents a tiny fraction of the overall elapsed
time during the system call. Finally, we have found cases where a Linux app running
under lxrun on a UNIX system will actually outperform the
same app running (without emulation) under Linux. We think
this is the result of the UNIX kernel being more efficient
at some tasks than the Linux kernel. So to summarize: The performance "penalty" will probably not
be noticeable -- and likely not even measurable. The one exception to this rule is X-Windows performance. Since
Linux apps can not use shared memory to communicate with a UNIX
X server, you may notice a slight slow-down in graphics-intensive
apps.
However, lxrun has survived for quite some time on contributions
of code from users just like you. In fact, the original Solaris
port was just such a contribution. Mess around with it. Maybe
you can get it to work. If you do, send us a patch!
In 1997, Michael released the lxrun source code to Steven Ginzburg
who is continuing its development as an open source project
under the Mozilla public license. Contributors to lxrun have
included hobbyists and engineers from all over the world.
In addition, the Santa Cruz Operation (SCO) and Sun Microsystems have
both contributed engineering time and other resources to the
project.
Effectively, you need to set up a "Linux environment" that
looks enough like a real Linux system to fool the program
you are trying to run. For more information, see the section
below on Linux environments.
Each line in the PATHMAP file is a separate entry. Each entry
consists of two parts: a path in the Linux environment and what
that path maps to in your native filesystem. For example: This tells lxrun that a Linux app attempting to access /dev/mouse
should actually use /dev/tty1a instead. Individual files or
whole directories can be remapped in this way. A plus (+) sign
in the "map to" field represents $LINUX_ROOT. For example: This entry tells lxrun that anything the Linux app tries to
access under /lib actually refers to $LINUX_ROOT/lib. This
sort of mapping is useful for keeping your native and Linux
libraries separate.
In the early days of lxrun, a Linux environment
was often just a big lib directory containing
lots of different Linux libraries acquired from different
sources at different times as they were needed.
A "style 1" PATHMAP file is based on this model; all
lib directories are remapped to a few central places. More commonly nowadays, people are using Linux environments
that look like (or are) real Linux systems. These environments
typically come from one of three possible sources:
See the section below on Linux environments for more information.
Consider the following shell script: ./linuxapp arg1 arg2
For lxrun to correctly execute "linuxapp", one of two things
must happen: either your operating system must allow direct
execution of Linux binaries (see Q1.5 below) or lxrun must
be helping the script interpreter (/bin/sh in this case) to
run, which probably won't be the case since /bin/sh is a native
binary. However, you can use the PATHMAP file to map /bin/sh
to a Linux shell, in which case the above script will work
correctly. To do this, install a Linux sh-like shell (e.g., "bash") in
$LINUX_ROOT/bin and add the following line to your PATHMAP file: This tells lxrun to use "bash" instead of "sh" to execute
the shell script. Since lxrun will be helping the shell
script run, "linuxapp" will be executed properly.
Note that there is a big difference between the Linux dynamic
loader (ld-linux.so.2) and lxrun masquerading as the Linux
dynamic loader (also called ld-linux.so.2). For lxrun to
work, you need a real Linux loader installed properly in
your $LINUX_ROOT directory.
Edit the Makefile. Look for comments containing the word "gcc".
Uncomment the commented-out gcc-specific lines and comment out
the native equivalent.
If your default shell is a C-shell derivative, you may need to
add the line "SHELL=/bin/sh" to the top of the Makefile. The reason the lxrun Makefile is so funky is because both SCO and
Sun want it to be compatible with their internal build systems.
Consequently, there's a lot of stuff in the Makefile that simply
isn't applicable to someone building from the WWW distribution.
Because of this, lxrun forms its Linux environment from a
combination of native files and Linux files. You store the
Linux files in a special directory and set the $LINUX_ROOT
environment variable to point to it. The PATHMAP file in
that directory tells lxrun where to find particular files --
whether to take them from the native filesystem or from the
miniature Linux filesystem in the $LINUX_ROOT directory. For example, the PATHMAP file usually maps /lib to
$LINUX_ROOT/lib. This means that when your app attempts to
access files in /lib (probably libraries) lxrun should look
in $LINUX_ROOT/lib for those files. That way the app will
find the Linux libraries instead of your native libraries
which are stored in /lib.
There is also a modified version on
this
site that allows you to mount Linux partitions that
are within DOS extended partitions. If you have problems with the driver, make sure you are
using the latest version. Recent improvements include
Solaris 8 support and support for more advanced versions
of the ext2fs filesystem.
This means that you're the first person who has gotten
around to mapping that particular system call.
Implementing the clone system call is only half the battle. Lxrun
itself must be made thread-safe so that it won't crash if the
application attempts to use two system calls at the same time
from two different threads of execution. One of the goals of
the 0.9.5-series development is to make lxrun thread-safe in
anticipation of implementing the clone system call. Once lxrun itself is thread-safe, the actual implementation of
the clone system call will not be entirely straightforward.
For one thing, lxrun must continue to run on four different
UNIX variants spanning three major realeases of System V. The
system with the oldest roots (OpenServer, based on System V
release 3) doesn't even have native thread support! Implementing
thread support in a system-independent way will be difficult,
if possible at all. There is one additional complication: There are plans for future
versions of the Linux kernel and GNU libraries to make changes
in the thread model. These changes involve mechanisms that are
impossible for lxrun to emulate because they are too similar to
the native System V (iBCS2) system call model. Once these
changes take place, the only way lxrun will be able to support
threads is with a shim library.
This glitch will only show up if you have a native library
installed that has the same name as a needed Linux binary.
If you have XFree86 installed on your native system, the
/usr/X11R6/lib libraries are common culprits. The best solution is to make sure no native libraries are
available anywhere under the directory pointed to by
$LINUX_ROOT.
First, check your libraries. Where did you get the Linux libraries
you're using? Are they fairly up-to-date? The most reliable way
to pick libraries is to take them from a Linux system that you
know can run the application in question. Avoid mixing libraries
from different Linux distributions or different libc versions.
Note that the libraries included with UnixWare 7.1 or found
on Skunkware may not work for you depending on what app you're
trying to run. If that fails, use the "-t" option to tell lxrun to produce a
system call trace while running your application. (You should
probably start with the "-t sys" option because it will give you
the most complete, yet concise output.) Here are some things
to look for in the trace dump:
A special thanks to:
Visit the lxrun web site at:
http://www.ugcs.caltech.edu/~steven/lxrun
for the latest news...
=== Section 0: The Basics ===
=== Section 1: Building and Using lxrun ===
/dev/mouse /dev/tty1a
/lib +
Since these environments are laid out like real Linux systems,
the PATHMAP file tends to be a direct mapping of certain important
directories.
#!/bin/sh
/bin/sh +/bin/bash
=== Section 2: Linux Environments ===
=== Section 3: Adding System Calls to lxrun ===
int lx_flock() { return enosys("flock"); }
=== Section 4: Troubleshooting ===
myprog: can't resolve symbol 'XXX'
The lxrun FAQ is maintained by Steve Ginzburg (steven at ugcs dot caltech dot edu)