![]() |
FreeBSD SysVR4 EmulationMark Newton, newton@atdot.dotat.org |
The emulator has been produced by a process of distillation, starting with the Linux and iBCS2 emulators from FreeBSD and the SVR4 emulator from NetBSD. HUGE thanks to Christos Zoulas and Todd Vierling for the NetBSD stuff, and David Greenman and Soren Schmidt for the FreeBSD stuff. I haven't so much written this stuff as integrated and debugged it, and couldn't have done it without the efforts of those individuals.
The emulator has some limitations, and needs a lot of work. The most most pressing items at the top of my to-do list are presented below; if you are interested in lending a hand, it'd probably be best to start with those.
If you use it, please provide feedback. If something doesn't work, ktrace output describing the failure would also be appreciated (although I'll get very rude if you bombard my mailbox with 50Mbyte ktrace.out files, so please be considerate).
I've tested the emulator with a variety of hand-rolled test programs and actual utilities from the Solaris 2.5.1 CD. The most complicated shell-based program which runs is "vi". Networking programs such as "telnet" and "ftp" work fine too, which means the SysVR4 STREAMS emulation is at least pretending to be functional.
1999-Jan-28: Committed the LDT patch as a lead-up to committing the whole emulator. Also cleaned up a crapload of warnings. There are still other cosmetic nits and major functionality botches, but it's better now than it was. svr4_sys_getdents64() and poll() are still broken, incidentally.
1999-Jan-11: I've merged most of Christos Zoulas' changes to the NetBSD
SysVR4 emulator into this one so that it can be relatively functional with
Solaris 2.6 libraries. Changes involved unstaticizing dosetrlimit()
in sys/kern/kern_resource.c, which is taken care of by the updated
installation patch. Despite the update, svr4_sys_poll()
and svr4_sys_getdents64() syscalls don't seem to be working as expected,
so more work needs to be done here. NetBSD's VOP_READDIR and
native poll() syscalls are different enough from FreeBSD's that
they can't JustWork(tm).
Lots of #if defined(NOTYET) stuff was removed too -- Solaris 2.6
libraries need a reasonable number of 64-bit system calls to work, so I've
had to bring 'em in. DNS name resolution doesn't work at present, but I
think that's related to the svr4_sys_poll() problem outlined above.
1999-Jan-06: The emulator is now a KLD ready for ELF 3.0.x (rather than an LKM, the FreeBSD 2.2.x kernel loadable object format). See the download section to get it. You'll need to re-fetch the svr4.tar.gz source module if you have an earlier version of the emulator already installed.
The distribution is broken into three parts. You'll need all three parts if you expect to get this bucket of bolts working:
Each distribution contains a README file in some semi-obvious location; The README files document things you'll need to do to make that sub-part do its thing (for instance, things you'll need to change in your kernel source tree to make the "streams" pseudo-device driver work). That information is reproduced below in the INSTALLATION section.
To make the emulator work you'll need a SysVR4 CD-ROM. I've been using Solaris CDs for testing, but there shouldn't be anything preventing SCO binaries from running (crosses fingers -- I've only tried a small subset of SCO binaries because SCO's habit of putting billions of symlinks all over the filesystem makes it all too hard to do large-scale testing at this point). SCO and Sun both give their x86 versions away for free for educational or private individual use, so it shouldn't be all that difficult to come across them. See http://www.sco.com and http://www.sun.com to find out how to get free copies of licenses and cheap installation media.
If you have everything working, you should be able to run the "hello" program provided in /usr/src/sys/modules/svr4.
Developers are extremely welcome, and actively encouraged. I've set up a majordomo mailing list to discuss the technical issues of SVR4 emulation; You can put yourself onto it by sending email to majordomo@atdot.dotat.org with the text "subscribe freebsd-svr4" in the BODY of the message.
Eventually this distribution will get rolled into the -current CVS repository. That'll make installing it sooo much easier!
I have some ideas on how to make that simple, but I'll need time. If anyone thinks they can assist, let me know. It should be a relatively light weight project technically speaking, and could be an ideal way for someone who hasn't hacked kernels before to make a contribution.
My development methodology has been something like, "xxx doesn't work. Find out what services xxx needs. Emulate them. xxx works now, therefore those services must be emulated correctly." While the first three steps are ok, the fourth represents a false conclusion. More extensive testing than I've carried out really needs to be done. Call me lazy :-)
In most cases I'm building on a fantastic foundation provided by Christos Zoulas from the NetBSD Project (this is really just a FreeBSD port of his code). In some cases, however (parts of signal delivery, the LKM framework, etc) there is code I've written which has been tested somewhat less rigourously.
You'll need to make other changes
to your kernel source code before
it'll work. See "INSTALLATION" below
for more information.
"All the SysVR4 programs I try say, `ELF binary type not known'"
A peculiarity of the FreeBSD ELF subsystem is that ELF programs need to
be "branded". Use the following command:
brandelf -f -t SVR4 program
[ substitute the pathname of your SysV program in place of "program" ]
yes, that means you can't run things straight off a SysV CD-ROM. Cope.
"X11 clients hang or tell me they can't open server :0.0"
X windows clients do work, you just can't use :0.0
as your $DISPLAY. Change it to unix:0.0; Solaris wants
to use a named pipe to talk to the X server if you use :0.0, but
XFree86 provides a socket (which can't be open()'ed). If you use
unix:0.0 the Solaris libX11 will use the socket.
Unfortunately the aforementioned poll() bug means TCP connections
to X servers hang. Let's just fix poll(), ok?
"Crudbox 3.1 from Foobar Enterprises doesn't work!"
Tell the mailing list you're working on it; Modify the emulator to make it work; Submit
patches to me.
I don't have huge numbers of SysVR4 apps, so I can't test everything. At this stage I expect people who submit bug reports to be able to send 'em in with patches. Sorry if this sounds harsh, but if I spend 24 hours per day working on everyone else's bugs I'll end up like Mike Smith :-)
kdump(1) doesn't seem to be reporting the right system calls
That's because ktrace(1) is seeing FreeBSD syscall numbers when you
ktrace a SysV executable. To find out what the SysV executable is
really doing, grep for the syscall name provided by ktrace in the
file /sys/kern/syscalls.c. That'll give you the system call number.
Then grep for that number in /sys/svr4/syscalls.master -- that'll
tell you the SysV system call that was really running.
Example: kdump tells you that a Solaris/x86 program has executed getrusage(0x28113000,0x1ea8). If you grep for "getrusage" in /sys/kern/syscalls.c, you get:
"getrusage", /* 117 = getrusage */
So grep for 117 in /sys/svr4/syscalls.master:
117 NOPROTO SVR4 { int munmap(void *addr, int len); }
... which tells you that the Solaris program was really running an "munmap" system call.
It sucks, but I've spent so much time on the emulator itself that I haven't finished porting linux_ktrace. I've done most of it; if anyone wants to take the bits I've done and finish them off, let me know.
Extract svr4.tar.gz and streams.tar.gz into /usr/src. Then follow the steps below. They take about half an hour to run through (including kernel building), and only need to be done once.
You can simplify your task by taking this patch, which was generated against 3.0-RELEASE. It promotes static symbols to global scope and edits /sys/conf/files as described below, and ends up modifying /sys/kern/kern_exit.c, , /sys/sys/socketvar.h and /sys/conf/files to do its work (so you'll need write permission on those files and should expect them to change as a result of running the patch). You can install it by running patch -p < svr4patch in /sys.
If you don't trust foreign patches and want to do things by hand, see below.
The symbols concerned are listed below, along with the files they belong to. Edit each of the files and "unstaticize" the appropriate symbols.
Symbol | Source File |
---|---|
M_ZOMBIE | sys/kern/kern_exit.c |
soo_read() | sys/kern/sys_socket.c |
soo_write() | sys/kern/sys_socket.c |
soo_close() | sys/kern/sys_socket.c |
dosetrlimit() | sys/kern/kern_resource.c |
Note that function call declarations need to be declared non-static both in their prototypes and the actual definition of the function.
It's easier and quicker than it sounds.
void *so_emuldata; /* private data for emulators */
(it should go just underneath "so_gen_t so_gencnt")
dev/streams/streams.c optional streams device-driver
103 streams SysV STREAMS network driver
pseudo-device streams 1
freebsd% cd /sys/modules/svr4
freebsd% make depend
freebsd% make
Expect it to compile with quite a few warnings at this stage (anyone who wants to fix them and submit patches is welcome to do so).
freebsd# make install
freebsd# kldload /modules/svr4.ko
4.0 Type svr4 instead of the
commands above to load the emulator. To make it automatically load
at boot time, set the svr4_enable flag to YES in
freebsd# cd /compat/svr4/dev
freebsd# sh SVR4_MAKEDEV all
The tar archive contains symlinks which expect you to have a Solaris for Intel CD-ROM mounted on /cdrom -- If that's what you actually have, congratulations, installation is completed and you can start seeing what applications you can actually run. If you only have v2.6 or v7 media, stay with us, we're working to improve support for that (2.5.1 and earlier is presently more "capable").
If you have some other OS CD, remove the symlinks and install that OS's /usr/lib, /lib, and so on within the /compat/svr4 heirarchy. Make sure you run the SVR4_MAKEDEV script as shown above, though, otherwise code which tries to do networking or UNIX-domain sockets won't work.
This will remove the need to brand executables, because it will make the kernel assume that unbranded executables belong to the SVR4 emulator.
If you get "ELF binary type not known" messages, see the mini-FAQ above.