On Apr 18, 2019, at 7:41 PM, Warner Losh <imp at
bsdimp.com> wrote:
On Thu, Apr 18, 2019 at 5:11 PM Paul Koning
<paulkoning at comcast.net> wrote:
...
Poor man's hypervisor, I like that.
That's reasonably accurate. RSTS/E had "run-time systems", originally the
interpreter, support library, and user interface of the BASIC-PLUS language machinery.
Starting in, I think, RSTS/E V5B, it was generalized step by step to become a collection
of such things: a user interface, execution environment, and other stuff. It might be
very narrowly tailored, like the TECO run-time system, it might be the interpreter library
for a language, like the FORTH and ALGOL run-time systems, or it might be a fairly
complete emulation of a different OS, like the RT11 and RSX run-time systems.
I know I ran BASIC-Plus, TECO and RT-11 binaries (FORTRAN code) on the RSTS/E system I
started out on (6C or 7.0, iirc). We also had some RSX-11 binaries too for something
I've long-ago forgotten.
I first used a very primitive version of this feature in V5B around 1975, to run an
assembly language program before there was any general RSTS support for doing that.
Yea, I couldn't recall if it was tailored or generic. I think it was, as you
say, tailored from massaged versions of the original executives, iirc, but maybe they
were reimplementations like the crazy glue code that we had at university that was an
RT-11 .SAV file with some weird glue to make it run in 7th Edition Unix that we ran on a
VAX 11/750 using the pdp-11 emulator hardware it had...
Warner
Each runtime system was a separate construct. The kernel has a number of services to
enable various things that need to be done, though. Here are a few.
1. Each executable file has an attribute naming the runtime system that will execute it.
For example, PIP.SAV would be handled by the RT11 runtime system not because of the .SAV
extension but because of the runtime system setting. This is vague like the #! line in
Unix shell scripts.
2. Various exceptions and interrupts during execution would be directed by the kernel to
"pseudo-vectors" in the currently active runtime system. For example, traps to
4 or 10 or breakpoint traps would be handled that way, as would control/C interrupts.
3. The RSTS/E kernel uses EMT for syscalls, but any unknown syscall would go to the EMT
pseudo-vector. This directly enables RSX emulation because that uses a non-RSTS EMT
(377). But RT11 uses many of the same EMT codes that RSTS does, so there an escape
technique was used ("prefix EMT"). If RSTS saw EMT 377 with another EMT in the
next word, it would handle that as a kernel request. Any other EMT (not preceded by 377)
would go to the RT11 runtime system. So EMT 0 is an RT11 request, EMT 377; EMT 0 is a
RSTS kernel request.
I think the code in the runtime system would typically not be the original OS code or
taken from it. Exceptions might be things like the executable file loader. But syscall
handling is different partly because it isn't concerned with scheduling or execution
blocking (those are kernel concerns) and partly because it is mapping the request to the
equivalent RSTS kernel request, not to device operations or things like that.
It's interesting that no Unix RTS was attempted that I know of. Perhaps that was too
hard because the OS services are so different (nothing like fork or pipe in RSTS, which
would be a concern). Even so, one of the RSTS developers converted csh into a runtime
system, so you could run shell scripts and csh command parsing -- but the programs would
still be DEC programs, not Unix ones. Unfortunately that code has been lost as far as I
know.
paul