> From: Paul Riley
> port Mini-Unix will create some demand for device drivers on the /03
> systems, so may be worthwhile to implement RAW device.
I'm not sure I understand this ("worthwhile to implement RAW device"); let me
explain what the removal of 'raw' I/O devices from MINI-UNIX really means, and
then ask what it is that you are after.
Early Unix (no idea about later ones) supports two classes of devices; 'block'
devices, which can be used to hold file-systems, and 'character' devices,
which cannot. (I seem to recall a paper, perhaps from the Unix BSTJ issue,
which talks about them in some detail.)
The former are those where the underlying physical device has restricted
semantics; they are block-addressable mass storage devices. All access to them
is via the system's block buffer pool, so reads/writes by the user of
arbitrary size and location are possible. 'Character' devices are everything
'Raw' devices are an interface to the devices of 'block' devices which does
not go through the system's buffer pool; I/O operations to them perform DMA
directly to the user process' memory. They are 'character' devices, in the
Unix device taxonomy. The only semantics available are those supported by the
hardware - e.g. seeks only to block boundaries.
So when I say that MINI-UNIX doesn't have 'raw' devices, it just means that
e.g. the RK disk controller device _only_ talks to the Unix block buffer
system; if a user program wants to look at the disk contents, it has to go
via that system.
So, with that in hand, what exactly is the need you forsee for raw devices
Also, I've started to work on getting the V6 RL driver to work in MINI-UNIX;
it should have been easy (just delete the charater device interface), but
for some reason it didn't work when I tried it. I'll look at it in more
> From: Jay Logue
> Are your other changes available anywhere?
Yeah, they're all up-loaded, and linked to from my 'Running MINI-UNIX on the
It's mostly done, but I'll probably continue to tweak it a bir.
If anyone notices any errors, or has questions that aren't answered there, etc
please let me know.
> Also, I was wondering if it might be useful to have a github repo with
> these changes. I'd be happy to help set this up.
Feel free to go for it, if people think it would be useful. (I'm not sure
there is a 'basic' MINI-UNIX repo to start on.)
> From: Paul Riley
> Always darkest before the dawn.
Well, we'll see.
I found _that_ one; process 1 managed to exec() init, do a fork(), and then
the child process exec()'d the shell - then that apparently died, and the code
in init falls through into:
execl(init, minus, 0);
when the single-user shell exits, so then init restarted; rinse, repeat.
So a _lot_ of the code in mch.s seemed to be working correctly; system calls
(2 exec()'s, and a fork()) worked, processing switching worked, device
interrupts (for the disk and console tty) seemed to be working.. Not sure
So I looked at mch.s again, to see what else _was_ there, and I noticed a
place where I used R0 as a temp - with the MFPS/MTPS thing to get to the PS,
BIS #340, PS
need to change to:
BIS #340, R0
and R0 was being used to hold an arg (in pword:), and was being bashed.
So I fixed it, and now the shell starts OK, but attempting to do any command
(e.g. "echo foo"), things hang (the shell doesn't fork). If I type the
interrupt character, the shell exits, and init restarts.
Oh well, hopefully this one won't be too painful to work out. The system's
mostly working, which I think will really help.
> Now to see if 'cc' works on an '-11/40'
Yeah, the C compiler works fine on a /40; so the SOB bug (or perhaps some
_other_ one I haven't found yet) must have affected it too.
The thing that's odd about that bug is that SOB works _sometimes_ on an /05;
the 'rkmx' on the distro tape will boot (which if the SOB _never_ worked, it
wouldn't). So there must be a data dependency somehow. John Wilson says the
SOB is very optimized, so maybe there's a bug.
> then back to the /03.
Well, I tried /03 version, and it doesn't work; /etc/init continually
The thing is that _every_ file except mch.s is identical between the '05'
version (which runs fine on the /40; above), and the /03 version. So the bug
must be in mch.s - unless there's somehow an /03 dependency somewhere else I
missed. I looked through init.c, didn't see anything.
is the mch.s source, if anyone wants to look through it and see if they see
anything. It's conditionalized for the /03; there's a very simple header file
for the 03 version) to set the flags (so one doesn't have to edit the main file
to change the flag settings).
I had a careful look at mch.s, before I started, checking all the added
conditionalized code; found one that could have been an issue (I was using a
temporary register, r0, that had needed data in it), but the rest all looked
OK. I have some ideas on how to proceed on working out what's going on, but
I'm done for today, gotta do other stuff.
> I suspect there must be an issue with the -11/05 emulation in Ersatz-11
There is. The C compiler on MiniUnix emits SOB instructions. The -11/05 doesn't
implement SOB; however, the instruction emulator in MiniUnix (emul.s) is
prepared to emulate it. (So MiniUnix should work fine on real -11/05's.)
However, when set to an -11/05, Ersatz-11 treats SOBs as NOPs; they fall
through without any effect. Without a trap, they can't be emulated either.
This caused the problem with namei() failing (namei() calls bcopy(), which has
a SOB in it), and probably caused the problem I was seeing with the C
compiler, but I'm too burned out to check right now. Tomorrow.
> I just realized that the _first_ entry, #'9', is actually #0 _in the
> directory_; u_count counts _down_, whereas the code looks through dir
> entries going _up_.
Fixed that (kept my own index of which entry it was working on, and
caculated the name location in the buffer, and got:
chk 0 15 2 '..'
chk 1 14 18 '.'
chk 2 13 34 'bin'
chk 3 12 50 'dev'
chk 4 11 66 'etc'
etc... and it blew right past the 'etc' entry, to the end of the
> Still don't understand why I can't print the dir entries out of the u
> area, though.
Now that my brain has turned on, I'll bet that's not _my_ bug, I'll bet it's
_the_ bug! If the directory entry in u.u_dent.u_name is all 0's, _of course_
the match is going to fail.
Just for grins, I set the CPU type in Ersatz-11 to "40 EIS NOMMU" and... it
booted up fine! I suspect there must be an issue with the -11/05 emulation in
Ersatz-11, since MiniUnix worked fine on _real_ -11/05's.
Now to see if 'cc' works on an '-11/40' - then back to the /03.
> it looks at the following entries:
> Anyway, after printing the entry for 5, it goes to 'done'
Uh, I just realized that the _first_ entry, #'9', is actually #0 _in the
directory_; u_count counts _down_, whereas the code looks through dir entries
Still don't understand why I can't print the dir entries out of the u area,
> From: jay-tuhs9915
> Are there any notes you can share on how to get to the point you're at?
Well, there are three areas where the /03 version needs work, over the /05:
- No LTC clock register
- No switch register
- PS access only via MFPS/MTPS instructions
For the first two, the needed changes are identical to the ones detailed here:
These have all been tested on the /23. Rather than anyone make the exact same
changes independently, I can put up the modified versions of the MiniUnix
files for them (low.s, main.c and param.h).
For the third, I have an mch.s with a conditional assembly flag that _should_
do it all; like I said, there are also really minor edits to bio.c, clock.c,
slp.c, and tty.c. Again, I can upload the mch.s which is already done.
I haven't been able to _confirm_ that these work, but it should be mostly good;
the changes are pretty straight-foward.
> The code is doing a string comparison between the name in the current
> directory entry (u_dent) and the current pathname component (in
> u_dbuf). The expression in brackets is the relative distance between the
> two name fields within the u struct.
Yeah, I'd worked that out (the immediately preceding comment in the code -
"String compare the directory entry and the current component" - indicates
what it's doing, and as my "the term inside the 's seems to be an offset
.. into the copy of the current directory entry" indicates, I'd worked out how
it did that. I was still puzzled by some othet aspects of the code, I just
included that to give a flavour of the code.
> In what way does it fail? Is it simply that namei() doesn't find the
> file its looking for?
Right. It's looking for 'etc' in the root directory (only one block), and
it looks at the following entries:
9 146 '05mx'
8 130 'usr'
7 114 'tmp'
6 98 'mnt'
5 82 'lib'
(I put a printf() in the loop; I've added prf.c to the load so I can do
that. The numbers are the index, u.u_count - although it's already been
descremented at that point, so it will be '0' when doing the last entry - and
location of that entry in the directory, given next to it. For some reason, I
can't get the entry to print from u.u_dent.u_name, so I'm printing it straight
from the block buffer, bp->b_addr. I can print the _inode number_,
u.u_dent.u_ino as a string, but not the dir entry. Wierd.)
Anyway, after printing the entry for 5, it goes to 'done', with u_error
containing '2'. I can't see how it could do that.
I'm using printf() because I'm too lazy to figure out how to build a kernel
with a debugger like DDT included. (We never did that when we were working
on V6 at MIT BITD; ISR we mostly just used printf() back then, too.)
>> Then on to trying to find out why MiniUnix crashes whenever I try and do
>> anything significant.
> I decided I wasn't up to tackling that, so instead I did all the edits
> to produce an LSI-11 version of MX. ... I need to go
> back and put conditional assembly flags in mch.s so there's only one
> source file for both kinds of system. Doesn't boot, though.
So this has turned into a big swamp.
I went back and did the conditionals, and I can turn off the -11/03 flag and
produce the identical binary to the original mch.o file. -11/05 systems built
with that still won't boot, though!
So I had made some minor changes elsewhere in the system; e.g. a few files
(bio.c, clock.c, slp.c, and tty.c) refer the the PS explicitly (a no-no in the
-11/03) so I changed them all to call getps() and putps(), and added /05
versions of those to mch.s; so I backed them out, and re-built the system
using the original binaries of those; _still_ won't boot.
I then tried the original 'rkmx', and that _does_ boot; so there's no
mysterious damage to the file system. But now I'm deeply puzzled, since the
new system (which won't boot) should be basically identical (OK, not
bit-for-bit identical, but close).
So then I started trying to see why the new /05 system won't boot; the exec()
call in process 1 that starts /etc/init seems to be failing. Digging into
that, the call to namei() (in sys1$exec()) seems to be failing? Huh? The
file-system is OK (see above)?
So I'm trying to work out how that is happening. Which is non-trivial;
namei() is pretty convoluted. I can deal with the fact that there are two
nested loops using goto's (not the best form, but I can grok it), but then I
run into things like this:
for(cp = &u.u_dbuf; cp < &u.u_dbuf[DIRSIZ]; cp++)
if(*cp != cp[u.u_dent.u_name - u.u_dbuf])
Check out that second line! (And Heinz didn't touch it; this copy is from the
V6 source.) I'm not sure I 100% grok it, but I think I get roughly what it's
doing: 'cp' seems to be a (moving) pointer into the filename being matched,
and the term inside the 's seems to be an offset from there into the copy of
the current directory entry in the 'u' structure. (Which is a constant, it
doesn't need to be recomputed each time around the loop, though.) It seems to
check most of the (wrong) directory entries OK, but then inexplicably (to me)
At this point I'm getting a bad feeling that there could be a sim issue; that
could also explain the problem I'm seeing with the crashes, when trying to run
'cc' under the as-distributed -11/05 version.`
I'm not a SIMH user, though (I'm an Ersatz-11 person); is there anyone who is,
who'd like to play with MiniUnix with me?