I've assembled some notes from old manuals and other sources
on the formats used for on-disk file systems through the
Additional notes, comments on style, and whatnot are welcome.
(It may be sensible to send anything in the last two categories
directly to me, rather than to the whole list.)
----- Forwarded message from meljmel-unix(a)yahoo.com -----
Thanks for your help. To my amazement in one day I received
8 requests for the documents you posted on the TUHS mailing
list for me. If you think it's appropriate you can post that
everything has been claimed. I will be mailing the Unix TMs
and other papers to Robert Swierczek <rmswierczek(a)gmail.com>
who said he will scan any one-of-a-kind items and make them
available to you and TUHS. The manuals/books will be going
to someone else who very much wanted them.
----- End forwarded message -----
But wasn't it tsort that did the heavy lifting to get things in order?
ar c foo.a `tsort *.o`
Ranlib just made it fast by adding an index..
There's a little more than that to ranlib.
Without ranlib, ld made a single pass through each library,
loading the modules that resolved unresolved symbols. If
a module itself had unresolved symbols (as many do) and
some of those symbols were defined in a module ld had
already passed, you were out of luck, unless you explicitly
told ld to run a second pass, e.g. cc x.o y.o -la -la.
Hence the importance of explicit ordering when building
the library archive, and the usefulness of tsort.
Ranlib makes a list of all the .o file in this archive and
the global symbols defined or used by each module, and
places the list first in the archive. If ld is (as it
was) changed to recognize the index, it can then make a
list of all the object files needed from this archive, even
if needed only by some file it will load from the same
archive, then collect all required modules in a single pass.
Ld could all along have just made two passes through the
library, one to assemble the same list ranlib did in advance,
a second to load the files. (Or perhaps a first pass to
load what it knows it needs and assemble the list, and a
second only if necessary.) Presumably it didn't both to
make ld simpler and because disk I/O was much slower back
then (especially on a heavily-loaded time-sharing system,
something far less common today). I suspect it would work
fine just to do it that way today.
Nowadays ranlib is no longer a separate program: ar
recognizes object files and maintains an index if any are
present. I never especially liked that; ar is in
principle a general tool so why should it have a special
case for one type of file? But in practice I don't know
anyone who uses ar for anything except libraries any more
(everyone uses tar for the general case, since it does a
better job). Were I to wave flags over the matter I'd
rather push to ditch ar entirely save for compatibility
with the past, move to using tar rather than ar for object
libraries, and let ld do two passes when necessary rather
than requiring that libraries be specially prepared. As
I say, I think modern systems are fast enough that that
would work fine.
Dear Unix Enthusiasts,
We are seriously considering upgrading our PDP 11/40 clone (SIMH), to a PDP 11/45 (preferably another SIMH) for our Unix v6 installation. Our CEO was traveling and met a techie in first class (seriously, first class?) who told him that we needed one. I thought I had better ask some folks who have gone before about it before we jumped on the bandwagon. By way of background, Our install is pretty small with a few rk’s and 256K of ram along with a few standard peripherals, and some stuff our oldtimers refuse to part with (papertape, card punch, etc). It has fairly low utilization - a developer logs in and writes code every few days and the oldtimers hunt the wumpus and play this weird Brit game about cows. It could be considered a casual development and test environment and an occasional gaming console.
Here is what I would like to know that I think y’all might be particularly equipped to answer:
1. Are there any v6 specific concerns about upgrading?
2. Why should we consider taking the leap to the 11/45? Everything seems to work fine now.
3. If we jump in and do the upgrade, how can we immediately recognize what has changed in the environment? I.e what are some things that we can now do that we couldn’t do before?
4. If we just insert our current diskpacks into the new system, will it just boot and work? Or what do we need to before/after booting to prepare/respond to the new system?
5. Is 256K enough memory or what configuration do y’all recommend?
6. Is there anything else we need to know about?
Sent from my iPhone
> From: Will Senn
> We are seriously considering upgrading our PDP 11/40 clone (SIMH), to a
> PDP 11/45 (preferably another SIMH)
Heh! When I saw the subject line, I thought you wanted to upgrade a
_physical_ -11/40 to an -11/45. ('Step 1. Sell the -11/40. Step 2. Buy
an -11/45.' :-)
> for our Unix v6 installation.
Why on earth would an organization have such a thing? :-)
> Our CEO was traveling and met a techie in first class (seriously,
> first class?) who told him that we needed one.
Heh. If said techie knows about the two, he's probably pretty senior (i.e.
eligible for Social Security :-), and thus elegible for first class... :-)
> It has fairly low utilization - a developer logs in and writes code
> every few days
Who the *&%^&*(%& is still writing code under V6?!
And how do you all get the bits in and out? (I run mine under Ersatz-11,
which has this nice device which allows it to read files off the host file
system; transfering stuff back and forth is a snap, I do all my editing with
Epsilon on my Windoze box, 'cause I'm too lazy to bring up the V6 Emacs I
> 1. Are there any v6 specific concerns about upgrading?
Not that I know of.
> 2. Why should we consider taking the leap to the 11/45? Everything
> seems to work fine now.
You're asking _us_?
Some larger applications will only run on an split-I-D machine, is about the
only reason I can think of.
Oh, also, the floating point instructions on the /45 are the only kind
understood by V6; the C compiler doesn't emit the ones the /40 provides. Any
floating point code run on the /40, the instructions are simulated by a
trap handler (by way of the OS, which has to handle it and reflect it to
the user process). I.e. very slow.
> 3. If we jump in and do the upgrade, how can we immediately recognize
> what has changed in the environment? I.e what are some things that we
> can now do that we couldn't do before?
> 4. If we just insert our current diskpacks into the new system, will it
> just boot and work? Or what do we need to before/after booting to
> prepare/respond to the new system?
Any V6 disk pack can be read/mounted on any V6 machine. Any binaries (the OS,
or user commands) for the -11/40 will run on the -/45. (Which is why the V6
dist includes binaries for /40 versions of the OS only.)
To make use of the /45, you need a different copy of the OS binary, built from
a slightly different set of modules. (Replace m40.s with m45.s; and you will
need to re-asssemble l.s, prepending it with data.s.) Both variants can live
on the same pack, under different filenames; select the right one at boot
> 5. Is 256K enough memory or what configuration do y'all recommend?
256KB is all you can have. Neither SIMH nor Ersatz-11 support the Able
which is what you need to have more than 256KB on a UNIBUS -11.
> From: Clem Cole
> You'll probably want to configure a kernel for the 45 class machine.
> Look at the differences in the *.s files in the kernel.
More importantly, look at the 'run' file in /usr/sys, which has commented
out lines to build the OS image for /45-/70 class machines.
> But either way you should configure the system to use the largest drive
> v6 has.
This is actually of limited utility, since a V6 file system is restricted to
65K blocks _max_. So a disk with 350K blocks (like an RP06), you'll have to
split it into like 5 partitions to use it all.
> From: Will Senn
> Do you know of some commonly used at the time v6 programs that needed
> that much space?
Heh. Spun up my v6, and did "file * | grep separate" in /bin and /usr/bin,
and then recalled that V6 was distributed in a form suitable for a /40. So,
Did the same thing on /bin from the MIT V6+ system, and got:
a68: separate I&D executable not stripped
a86: separate I&D executable not stripped
bteco: separate I&D executable not stripped
c86: separate I&D executable not stripped
e: separate I&D executable not stripped
emacs: separate I&D executable not stripped
lisp: separate I&D executable not stripped
mail: separate I&D executable not stripped
ndd: separate I&D executable not stripped
s: separate I&D executable not stripped
send: separate I&D executable not stripped
teco: separate I&D executable not stripped
No idea what the difference is between 'teco' and 'bteco', what 's/send' do,
> Is there any material difference between doing it at install time vs
> having run on 11/40 for a while and moving the disk over to the 11/45
No; like I said, you can have two different OS binaries on the disk, and
select which one you boot.
> On a related note, how difficult is it to copy the system from rk to
> hp? I know I can rebuild, but I'm sure there's a quicker/easier method...
Build a system with both, and then copy the files? I'd use 'tar' (I have a V6
tar, but it uses a modified OS with the smdate() call added back in) to do the
moving (which would retain the last-write dates); 'tp' or 'stp' would also
The hack _I_ used on simulated systems was to expand the file that held the
'disk pack', mount it as a different kind of pack (RL or RP), and then go in
and hand-patch the disk size in the root block with 'db', then 'icheck -s' to
re-build the free list. Note: this won't give you more inodes, so you may run
out, but the usual inode allocation is pretty generous.
PS: Speaking of the last write dates, I have versions of mv/mvall, cp/cpall,
ln, chmod etc which retain them (using smdate()). If there's an actual
community of people using V6, I should upload all the stuff I have. Although
it might be good to establish some central location for exchange of V6 code.
However, I don't and won't (don't even ask) use GitHub or any similar modern
> From: Will Senn
> I whacked /usr/sys/lib1 and lib2 'accidentally' meaning I logged in as
> bin changed to /usr/sys and typed rm lib1 and rm lib2 :).
Doesn't sound very accidental... :-)
> sh run as bin doesn't do it.
Odd. 'run' in /usr/sys on my V6 machine (not that I use that, mind) says:
cc -c -O *.c
ar r ../lib1
cc -c -O *.c
ar r ../lib2
which should regenerate them - sort of. I suspect you really meant 'doing sh
run creates a lib1 and lib2, but then I get errors from the ld phase with
missing symbols'. Yes?
If so, the thing is that the V6 linker won't pull in an object module from a
library unless a global in it satisfies an already existing (i.e. in the
linking process) undefined global. (I don't know if this is true of later
linkers; never used 'em.) In other words, when loading a multi-module system,
the module with 'main' has to be first, and then the rest in an order such
that each one holds a previously-undefined symbol.
So the order of the object modules you'll get in lib? from the above, if you
precede them with 'rm lib?', is probably not the right order. (The above shell
script assumes they already exist, with the modules in the right order, so the
above just replaces them with the newly compiled versions...)
> So, what magic incantation is required to rebuild them.
Here's the ordering in lib1:
Other orders would work too (e.g. you could move sys?.o up just after sysent.o
and it should work).
My lib2 is somewhat odd, so I hesitate to list it, but since most modules in
dmr are pulled in from entries in c.c, almost any order will work, I think.
> From: Will Senn
> Thanks for not dismissing the thread as frivolity.
Hey, anyone wanting to do things with V6 I take seriously! :-)
> I'm sure y'all have seen Mills's winning Best in Show IOCCC entry:
Yes, that was pretty awesome.
> Fantastic, I'm prolly gonna try it.
OK; if you want to know what it's doing (somehow I figured you probably didn't
just want to simply follow the instructions :-) that is different from the /40
(it's quite different, and somewhat complicated), I just wrote this:
to explain it a bit. Currently, one has to read the source to 'sysfix', and
also m45.s, to understand how the /45 version works; that new page is a little
crude still, but it hopefully explains the big picture.
> If the instructions in Setting up are as good for the 45 as they are for
> the 40, I should be able to bring one up relatively painlessly.
I just took a look at "Setting up UNIX - Sixth Edition", and it doesn't really
say much about the /45; it basically just says 'the /45 is wiered inside' and
'look at sys/run'. It is certainly true that that does cover all one needs to
bring V6 up on the /45, but... The coverage of what to do if your '45' has
hardware floating point is pretty complete, though.
> What it sounds like is that Unix was transitioning from non-I/D land to
> I/D land and maintaining a measure of backward compatibility
That's pretty accurate. One main advantage of the /45 is that it could have a
lot more disk buffers, but I'm not sure that makes much difference for
emulation. If you have some application that won't fit well in 64KB, that's
big, but that's a user-land difference, not the OS.
> Is there a bootable tape of the MIT system extant?
Not yet, sorry. I do have a complete dump, but it i) includes all the users'
personal files, and ii) is not well organized. It's on my to-do list.
> But wasn't it tsort that did the heavy lifting to get things in order?
An amusing notion. Having written tsort, I can assure you it couldn't
lift anything heavy--it used the most naive quadratic algorithm. But
it was good enough for libc.
>Date: Sun, 30 Dec 2018 14:24:55 -0500
>From: Paul Winalski <paul.winalski(a)gmail.com>
>To: Norman Wilson <norman(a)oclsc.org>
>Subject: Re: [TUHS] Deleted lib1 and lib2 in v6, recoverable?
>Content-Type: text/plain; charset="UTF-8"
>On 12/30/18, Norman Wilson <norman(a)oclsc.org> wrote:
>> Nowadays ranlib is no longer a separate program: ar
>> recognizes object files and maintains an index if any are
>> present. I never especially liked that; ar is in.
>> principle a general tool so why should it have a special
>> case for one type of file? But in practice I don't know
>> anyone who uses ar for anything except libraries any more
>> (everyone uses tar for the general case, since .it does a.
>> better job).
>As you say, nobody these days uses ar for anything except object
>module libraries. And just about anything you do that modifies an ar
>library will require re-running ranlib afterwards. So as a
>convenience and as a way to avoid cockpit errors, it makes sense to
>merge the ranlib function into ar. MacOS still uses an independent
>ranlib, and it's a pain in the butt to have to remember to run ranlib
>after each time you modify an archive.
Maybe not on some of the older, more (resource) restricted systems,
but now normally wouldn't modifying an archive be part of
definitions/rules in a makefile and as such wouldn't the makefile
include using ranlib if an archive was modified ?