Lxrun (from the README)

lxrun is an emulator for executing Intel Linux a.out and ELF binaries on other Intel x86 unices. It was developed principally on and for SCO OpenServer and SCO UnixWare.

It works by remapping system calls on the fly. There's not a great deal of difference between the execution environment required by Linux and SCO binaries, the main one being 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 SCO systems, "int $0x80" causes a SIGSEGV signal. lxrun intercepts these signals and calls the SCO equivalent of the system call that the Linux program attempted. There's also some mapping of ioctls, various flags, return values, and error codes. The result is that the Linux binary runs (with the help of lxrun) on the host platform with a small (usually negligible) performance penalty.

Since lxrun is effectively a system call emulator it requires copies of the Linux dynamic loader (ld-linux.so.1) and whatever Linux shared libraries are required by the program being run.

Most programs that do not rely on Linux-specific quirks or deal directly with hardware should work under lxrun.

The official lxrun web page is http://www.ugcs.caltech.edu/~steven/lxrun/

What works?

Well, apart from what you can find at the official web site, most things we've tested. Aside from the obvious things bundled with Red Hat 5.2 (rpm, shells, and non-/proc commands) here's the biggies:

We ran these at the LinuxWorld show in San Jose in March 1999. Because lxrun requires the supporting libraries and such from a Linux installation (in our case, Red Hat 5.2, ) I ported the Linux ext2 filesystem to Solaris. This makes it simple if you dual boot Linux and Solaris on a machine - just mount the Linux ext2 filesystem on /linux, point lxrun at it, and off you go. The hardware we used at the show, mostly because we were able to scrounge it out of the labs, consisted of this: 400Mhz Pentium II (1 UP, one 2-way), 128Mb, on-board ATI Rage 3d Pro. Quake2 was run with no hardware acceleration, we just used the software X renderer with the shared memory extension.

Where can I get this incredible software?

Soon you'll be able to get it from http://www.sunfreeware.com . There will even be a much more spiffy version of this page on the Sun web site, possibly at http://www.sun.com/software/linux But for now, you can get it here:

  1. lxrun: lxrun.tar.gz is a gzip-compressed tar file of my lxrun workspace. A precompiled binary is inside that was built on Solaris 7.

  2. ext2 filesystem support: ext2fs.tar.gz is a gzip-compressed tar file of my ext2fs filesystem and source. Inside is precompiled ext2fs modules and mount commands for both SPARC and x86 (also for Solaris 7). It only supports read-only access now, but seems pretty stable.

  3. Quake2 support files: quake2-3.20-6.i386.rpm, quake2-3.20-glibc-6.i386.rpm, quake2-3.20-i386-unknown-linux2.0.tar.gz, and quake2-3.20-glibc-i386-unknown-linux2.0.tar.gz are the Linux Quake2 binaries for glibc and non-glibc based Linux, in both RPM and gzipped tar format. These are also available from ID software, but are included here in case they change incompatibly (these are the ones we used for testing and at LinuxWorld). You'll also need the pak files from the Quake2 CD (which you have to buy).

  4. Sound drivers: www.4front-tech.com makes Open Sound System drivers, which work on a variety of platforms, including Solaris. They provide the API that Quake2 uses for sound. (It's embarassing that we don't provide base sound support in Solaris). A couple of notes - they don't work on a DEBUG kernel (DEBUG catches a bad bcopy() from the driver, apparently), and if you have a startup script to enable the sound like they suggest, it has no effect because the modunload that runs at the end of /etc/rc3 will unload the driver. So I just wrote a Quake2 wrapper that enabled the drivers instead.

How do I use it?

  1. Setup a Linux distribution for Solaris to access somewhere. This could be done any number of ways, such as off another disk through the Solaris ext2fs filesystem (described below), from a copy, or directly via NFS from a Linux machine. By default, lxrun will look for this distribution in /usr/local/linux, but you can set the environment variable LINUX_ROOT to wherever you really put it. This is Important Thing #1.

  2. Untar the lxrun tar file, and either build it from source (preferred), or grab the prebuilt lxrun binary. The Makefile is setup to build for Solaris, the final source from the official web site will probably use configure (as it does today if you get lxrun from that site). Place the binary wherever you like.

  3. Important Thing #2 is the PATHMAP file. This file tells lxrun how to remap file accesses when the Linux binary tries to open files. For example, if the Linux binary tries to open /etc/passwd, it probably doesn't want to see the Solaris /etc/passwd, but the Linux one. So lxrun translates a request to open /etc/passwd into a request to open $LINUX_ROOT/etc/passwd. The PATHMAP file controls what is remapped and how - we remap pretty much everything. By default, it looks for /usr/local/lxrun/PATHMAP, but you can set the environment variable LINUX_PATHMAP to the actual place you've got lxrun (such as /home/mike_s/lxrun/PATHMAP).

Now you can should just be able to run 'lxrun '. Such as 'lxrun /usr/local/linux/usr/bin/netscape', or, if you want to be in a completely Linux world, start a shell 'lxrun /usr/local/linux/bin/csh'.

Nameservice issues: your account _probably_ needs to be visible to both Linux and Solaris applications. If the Linux setup you're using can't look you up, applications run by lxrun will also not be able to find you. This can mean that the application won't run (applix), will core dump (gnome), or just won't work properly. The simple thing to do is to make sure you're in the Linux /etc/passwd file. If you're using a nameservice, like NIS, you have other possible problems - applications might wedge when trying to look you up because they cannot contact the nameservice. For example, if you're dual-booting Linux and Solaris, and mounting the Linux filesystem, Linux apps will try to look for the file /var/yp/binding/.2 in the linux area. If they don't find it, they hang. The problem is that when Linux is shut down properly, ypbind will _delete_ that file, so it won't be there when running Solaris. A solution under Linux is to copy that file, kill ypbind, then restore the file before shutting down Linux.

Installing ext2fs

  1. Untar the ext2fs tar file, and either rebuild from source (preferred) or use the prebuilt binaries.

  2. From the right directory (sparc or i386), copy the "ext2fs" module to /usr/kernel/fs and the "mount" binary to /usr/lib/fs/ext2fs/mount. I run this getext2fs script to install it on my test machines. Sorry, no 64-bit module yet because I don't have a sun4u running Linux to test on.

  3. Find your Linux drive and add an entry to /etc/vfstab for it. On sparc, the entry might look like this: On x86, it might look like this: (use "yes" instead of "no" if you want it mounted at boot). This is just for the root drive, add more if you need to mount other partitions.

Known ext2fs bugs

  1. See the "notes" file for my complete ramblings.

  2. No write support.

  3. Rebooting may fail to sync the filesystem (only because ext2fs is not releasing resource correctly, other filesystems should still be properly sync'd). This mostly seems to happen when you export ext2fs over NFS.