# bas
i=25
print i
2.50000000e1
for i = 1 10 print i next
1.00000000e0
2.00000000e0
3.00000000e0
4.00000000e0
5.00000000e0
6.00000000e0
7.00000000e0
8.00000000e0
9.00000000e0
1.00000000e1
So, that's asm, C, fortran, basic, and shell: 5 languages.
I'm sure we could get ed and roff to perform as turing machines, but
I will leave that as an exercise for the reader :-)
Warren
This is cool stuff. Just a few weeks after thinking "this would be
cool if we could rebuild a working early Unix from the printed source
code" you've done just that. While it seems pretty primitive, it's
certainly recognizable as a Unix already and LIGHTYEARS ahead of
anything else I've played with from that era (DOS-11 and RT-11)
Still no great progress. I can confirm that "cc" and "cvopt" both work, but
the two compiler passes "c1" and "c2" don't work. Sometimes I can get them
to core, but with different arguments the system locks up.
On http://cm.bell-labs.com/cm/cs/who/dmr/primevalC.html, Dennis notes this:
A second, less noticeable, but astonishing peculiarity is
the space allocation: temporary storage is allocated that
deliberately overwrites the beginning of the program,
smashing its initialization code to save space. The two
compilers differ in the details in how they cope with this.
In the earlier one, the start is found by naming a function;
in the later, the start is simply taken to be 0. This
indicates that the first compiler was written before we had
a machine with memory mapping, so the origin of the program
was not at location 0, whereas by the time of the second,
we had a PDP-11 that did provide mapping. (See the Unix
History paper). In one of the files (prestruct-c/c10.c) the
kludgery is especially evident.
It could be that this sort of memory operation is what is causing the
problem. Is there a way for simh to give an instruction trace beginning
at a certain address e.g. 040000, so I can watch c0's behaviour and see
where it goes off the rails?
Thanks,
Warren
I entered init.s and played around with it a little. I *think* it might
be working (I stepped through some of it) but it doesn't use the normal
tty in multi-user mode, so it's hard to tell without dc-11 support.
I guess it was lucky that we used the s2 init instead of the jun72
init, because it seems the s2 init does run getty on the main terminal
in multiuser mode.
The process for building it is:
$ tools/rebuild
$ tools/as sys1.s build/init.s
and you'll have a "b.out" in the current dir.
Is anyone planning on working on dc-11 support?
Tim Newsham
http://www.thenewsh.com/~newsham/
Now that we have 0407 kernel support, I'll have a go at getting one of the
early C compilers to work. Could I suggest that we make a src/ directory
in svn, which will hold any source code that produces V1/V2 executables?
I'll make a directory for the C compiler. We can also add in working fragments
from the s2 tape into a cmd/ directory. The layout echoes the V7 tree:
/usr/src
/usr/src/cmd/ # Single file sourcefiles
/usr/src/cmd/as/ # Assembler
/usr/src/cmd/c/ # C compiler
/usr/src/libc/ # C library
/usr/sys/sys/ # Kernel source
Which of course implies that we might need to rename rebuilt/ to sys/ :-)
Thanks,
Warren
After e-mailing a reply about 6 times today and it going to the original
poster, instead of the mailing list where I wanted it to go, I have
decided to change the behaviour of the unix-jun72(a)tuhs.org list. Replies
will now go back to the list, not the poster.
It's an arbitrary decision; if you disklike it, let me know. If most
of you prefer it the other way, I'll switch it back!
Good night,
Warren
I reorganized the build process slightly. Hopefully this won't affect
anyone and everything will keep working as before. I basically
took the 'sed' hacks out of assemv7 and made the "rebuild" script do
the patching with proper patch files instead. There is now a patches
directory with all of the patches we are using and comments on what
they do and why.
Tim Newsham
http://www.thenewsh.com/~newsham/
All, my mkfs.c $Revision: 1.17 $, $Date: 2008/05/04 14:20:12 $ now produces
mountable filesystem images, and it's now checked into the svn repository.
The problem was that the size of a directory is not the size of the blocks
allocated to it, but is in fact the number of bytes of the in-use directory
entries. For example, / was being allocated 1 block == 512 bytes. But 512
is not its size (as it would be in later UNIXes); in fact if / has entries
41 sdrwr- 7 root 70 Jan 1 00:00:00 .
41 sdrwr- 7 root 70 Jan 1 00:00:00 ..
43 sdrwr- 2 root 570 Jan 1 00:00:00 bin
42 sdrwr- 2 root 250 Jan 1 00:00:00 dev
99 sdrwr- 2 root 100 Jan 1 00:00:00 etc
108 sdrwr- 2 root 70 Jan 1 00:00:00 tmp
114 sdrwr- 2 root 20 Jan 1 00:00:00 usr
then its size is 7 entries * 10 bytes each = 70 bytes.
Importantly, this also means that we can now make bootable root filesystems
without having to do a cold UNIX:
% tools/mkfs /usr/local/src/V1 rf0.dsk rf # Make the / disk
% tools/mkfs /usr/local/src/V1 rk0.dsk rk # Make the /usr disk, same stuff
% ./simh.cfg
PDP-11 simulator V3.7-3
./simh.cfg> #!tools/pdp11
Unknown command
Disabling CR
Disabling XQ
RF: buffering file in memory
TC0: 16b format, buffering file in memory
sim> g
:login: root
root
# /tmp/a.out
/dev/rk0# ls -l /usr/tmp
total 8
112 sxrwrw 1 root 156 Jan 1 00:00:00 a.out
110 sxrwrw 1 root 1664 Jan 1 00:00:00 etma
113 sxrwrw 1 root 6 Jan 1 00:00:00 hello
109 sxrwrw 1 root 26 Jan 1 00:00:00 ttmp
111 sxrwrw 1 root 142 Jan 1 00:00:00 utmp
# df
806+4602 # Number of free blocks on / and /usr
I added /usr/tmp/hello just to verify that I was getting files that
were not on the cold UNIX tape.
Cheers,
Warren
> > The controller is an RK11.
> > The disk drives are RK02, RK03, RK05.
> >
> > The RK02 is a 1.2MB drive (256B per sector).
> > The RK03 is a 2.4MB drive (512B per sector).
> > The RK05 is a 2.4MB drive (512B per sector).
>
> There was also a RK05F which used a fixed platter (in the same
> plastic enclosure as the removables if I remember correctly). That was
> double capacity, around 5MB.
Yes, the RK05J is the removable one, as described above. The RK05F is
the fixed version that doubles the density. However, to the system, it
appears as two separate drives, not as a single 5MB drive. I am not
sure how the data were interleaved between the two "logical drives"
which is important when scheduling seeks on the logical drives.
James Markevitch
I've just checked in my latest tools/mkfs.c into the svn repository. Could
a few people eyeball it and look for errors. Even better, if you can eyeball
the working rf0.dsk image and compare it to an image made by my mkfs.c.
At present, I can make an rk0.dsk image with mkfs. I can run up a warm kernel
and try to mount the rk0 image as /usr, with my /tmp/a.out. But when I try
to chdir /usr, I get a Bad directory message.
So something is screwy with the rk0.dsk that my mkfs.c is making.
Thanks,
Warren
P.S typescript of warm boot:
:login: root
root
# check # check indicates rk0.dsk is OK
RF:
119 files
6 large
6 indirect
255 used
399 free
336 missing
RK:
43 files
0 large
0 indirect
2 used
4784 free
0 missing
# /tmp/a.out # I try to mount it
/dev/rk0# chdir /usr # but the chdir fails
Bad directory
# du /usr # du /usr shows no results
# df /usr # and df shows it is empty
0
# df # but df shows the free space on RF/RK
399+4784
> Confusingly, the 1e manual for /dev/rk0 says its an RK03. I'll have to go
> read the DEC manuals, but I would guess that the RK11 drive and interface is
> the same, but the RK03 and RK05 removable disk packs were of different
> storage capacity.
The controller is an RK11.
The disk drives are RK02, RK03, RK05.
The RK02 is a 1.2MB drive (256B per sector).
The RK03 is a 2.4MB drive (512B per sector).
The RK05 is a 2.4MB drive (512B per sector).
The media for the RK03 and RK05 are compatible (IBM 2315). The drives
look different from each other, but I don't think the system can tell
the difference.
James Markevitch
I looked through init briefly and the version from s2.tar.gz is
slightly different than the one in the pdf printout. In the printout
/dev/rk0 is mounted on /usr at boot time. In the s2 version the
string "/usr" is still present, but the call to mount is gone
and so is the "/dev/rk0" string.
The init source is fairly short and shouldn't be too hard to type
in or get from ocr. Has anyone yet worked through the details of
using the V7 compiler to make 0405 binaries? Also has anyone
successfully used a populated /usr on rk0 yet?
Tim Newsham
http://www.thenewsh.com/~newsham/
I wrote this:
exit = 1.
mount = 21.
sys mount; rk0; usr
sys exit
rk0: </dev/rk0\0>
usr: </usr\0>
And tried to assemble it with /bin/as, but it's a 407 exec and it didn't
work (core dump, created odd files)
So, I built it with apout & as like this:
apout /backup/raid2/pdp11/v7/bin/as ./mount.s
# reconsruct v1 0405 a.out header
echo -e '\005' >mount
dd if=a.out of=mount bs=1 skip=1 seek=1 count=11
dd if=a.out of=mount bs=1 skip=16 seek=12
And it runs, but nothing happens. I have not debugged it much. Wish we
had a working v1 as.
-brad
On Sat, May 03, 2008 at 08:16:19AM -0400, Brad Parker wrote:
> The simh setup was wrong; you need to use
>
> set rk0 enabled
> attach rk0 rk3.dsk
>
> Once I did that I could check the image I made with your program. I have
> not mounted it yet, however. It checks fine.
>
> Tim - where did you get the files you used to make your tape image? Can
> you tar up that directory and check it in? I can't find init anywhere.
> I must be confused.
On the s2 tape in /etc/init.
Thanks Brad.
Warren
> >There is a bug in the svn sources on page e09-07, near the bottom.
> >The call to sleep should read:
> >
> > jsr r0,sleep; 0:..
> >
> >Note that there should be a colon, not a semi-colon after the 0.
> >Presumably, this code was never executed, else it would have
> >resulted in a halt.
>
> thanks!
>
> but what *does* that syntax do? 0:.. ?
The two-instruction sequence is:
movb tty+3(r1),0f / put clist id in sleep argument
jsr r0,sleep; 0:..
The "0:" on the second line is a label and it is referenced by the "0f"
in the first line. The first line is putting a value into the argument
being passed to the sleep subroutine. Self-modifying code.
The ".." assembles to a 0.
With the incorrect code, "0" assembled to a 0 and ".." assembled to
a 0, so there was one extra word of zeroes, and the return from the
sleep would have executed it (halt) instead of the "br 1b" on the
next line.
James Markevitch
I downloaded the stuff from the svn, got it to build, then did a cmp -l
on the load file from my assembler vs. the one built from the svn tree.
There is a bug in the svn sources on page e09-07, near the bottom.
The call to sleep should read:
jsr r0,sleep; 0:..
Note that there should be a colon, not a semi-colon after the 0.
Presumably, this code was never executed, else it would have
resulted in a halt.
After I made that fix, a build from the svn tree is identical to that
from my assembler.
James Markevitch
I thought I would quickly make a list of commands we have, commands that
are missing, and out-of-the-ordinary commands. Below, if a command has
no comment, it's a V1 command that we have. Notes follow. I have not tried
to list the missing /etc and /usr/... commands yet.
/bin
----
: V2 cmd, 0405 binary
ar
as V2 binary
b missing
bas
bcd missing
boot missing
cal
cat
cc V2 binary
chball ? no idea
check
chmod
chown
cmp
cp
date
db
dbppt missing
dc
df
ds V2 binary
dsw
dtf missing
du
echo V2 cmd, 0405 binary
ed
exit V2 cmd, 0405 binary
fc V2 binary
find V2 binary
form
goto V2 cmd, 0405 binary
hup missing
if V2 cmd, 0405 binary
lbppt missing
ld V2 binary
ln
login V2 cmd, 0405 binary
ls
mail
maki V2 binary
mesg
mkdir
mkfs
mount
mv
nm V2 binary
od
pr
rew
rkd missing
rkf missing
rkl missing
rm
rmdir
roff
sdate missing
sh
size V2 binary
skip ? no idea
sort
stat
strip V2 binary
stty V2 cmd, 0405 binary
su
sum
tap
tm
tty
type
un V2 binary
wc
who
write
/etc
----
as2 V2 binary
getty V2 cmd, 0405 binary
glob
init
msh
suftab
uids
I have a quote from dmr somewhere (I can't find it), but to paraphrase:
early UNIX was under a constant state of development. We would tidy up
now and then, write a new manual, then get back to development.
The 1st Edition UNIX manual is dated November 3, 1971.
The 2nd Edition UNIX manual is dated June 12, 1972.
1st Edition (1e) only used 0405 a.out files. 2nd Edition (2e) only used
0407 a.out files. I would guess that the executables that we have from
the s2 tape are from a snapshot halfway between 1e and 2e, and at that
point in time the kernel could execute both varieties. This would explain
why some V2 commands are 0405 style, and some are 0407 style.
Despite the dates on the PDF commentary where we got the kernel source,
the kernel has to be around 1e, not much later. The kernel only knows
about 0405 a.out files, and is missing all of the system calls new to 2e:
hog, kill, makdir (renamed from 1e mkdir), smdate and sync.
So: kernel is around 1e, Nov 1971 or close; executables are somewhere
between 1e and 2e, but before June 1972 as we have 0405 and 0407 ones.
Cheers,
Warren
The tape I made earlier didnt properly preserve the permissions so
booting failed to exec /etc/init (had no exec bit set). I fixed
my tape builder to get the permissions from the old Readme file
and regenerated a tape..
The good news: login prompt!
I just built rf0 in the usual way, then rebuilt a warm kernel and
booted it.
Tim Newsham
http://www.thenewsh.com/~newsham/
Here's the current status on how to use the files:
- svn to the latest version
- install v7 binaries somewhere (ie /tmp/v7)
- install apout somewhere (ie /tmp/apout2.3alpha2)
- update paths in tools/assemv7
- compile tools/ml.c into tools/ml
- build simh's pdp11 emulator using brad's patches at
http://www.unlambda.com/download/pdp11/unix-jun72/KE.diff
install into tools/pdp11
- run ./tools/assemv7 to make files in build/*
- run ./simh.cfg to run the emulator
- type "go" to start it
- type "go" at the first halt to continue writing over your rf0 disk
- after waiting for a while, type control-e and then "det rf" and
then "quit"
- you should now have some data written over your rf0.dsk image.
Next steps:
- continue debugging the cold boot process. This should eventually
let us install a full root disk image from the kernel and a
tape construct with 1972_stuff s2 /bin and /etc files.
- get a working mkfs and use it to build and populate the rk03 disk
with the 1972_stuff s2 /usr files.
- continue debugging the kernel to boot the rf0 disk and mount the
rk03 disk on /usr.
Tim Newsham
http://www.thenewsh.com/~newsham/
Hey guys.
I saw the thread about the assembler doing divide by 2 the wrong way.
I took a look at my assembler and it had a similar bug. I fixed my
assembler, then ran the code again.
It correctly writes the RF11 image (as best as I can tell), then reads
/etc/init into the user area and executes it. I left the TC11 disabled
on my run and it panics when /etc/init tries to read the tape.
To double-check, I ran the warm boot and it successfully gets into
the /etc/init user code as well, so I'm pretty confident the image
is right.
As far as I can tell, the source code I sent out this morning has no
problems. Most likely, you guys are fighting assembler and/or other
tool issues.
I'll cobble together a bootable RF11 image (assuming that there really
are no kernel problems) and send out a copy of that. Once everyone
has that, they should be able to continue generating tapes and RK03
images of other executables, etc. I can include a copy of the
assembler listing file for both warm and cold boots so that everyone
can have a reference while they are debugging.
I've also got the M792 boot (from the documentation) as well as an
untested bos.s. If those work, then the RF11 image I send out will
be pretty close to authentic. Otherwise, you will still need to load
the kernel into core with the "load" command.
James Markevitch
I'm sending Brad a copy of a different OCR of the document that he
can use to check against the current one. The file also includes
various fixes to bugs in the original document.
Presumably, he'll incorporate anything differences into the svn.
James Markevitch
I just did a 'grep' of some suspicious
character combinations and found the following:
e00-04:/ initialize i-nodes r1.,...,47. and wr1te the root device,
binary, etc.,
e04-01: bne 3f /Is1t zero now?
e08-05: bis $103,r3 / now rbn,for,un1t,1e
e04-03:1: / flle just opened
e05-04: cmp r1, ii / r1 = i-number of current flle
e03-01: jsr r0,rswap / read new process 1nto core
e04-04: cmp r1,$12 / is char a l1ne feed
e06-02: br ret / it 1n r1; 1f there 1s no problem with reader,
it
e06-02: inc *u.fofp / increment file offset to point to 'next' char
1n
e08-03: br 1f / branch if block already 1n a I/O buffer
e08-03: bis $2000,(r5) / set read mu (bu: 100 1n 1/0 buffer)
e08-06: bit $173000,(r5) / lock+keep+active+outstand1ng
e11-07: cmp 0b,$1nbuf+256. / have we exceeded innut buffer size
e06-04: inc *u.fofp / increment f11e offset to point to next
available
e06-05: mov r2,i.size / yes, increase the f11e size to file offset +
e06-06: / be written to the f11e
e08-03:tstdeve: / check whether permanent error has occured on special
f11e
e03-02: / to end of stack gets written out) ~
e08-03: mov u.base,r2 / put users base in r2 ~
e11-01: cdpb B(r5),$'- / was this sh calleZd by init or loginx~
e03-02: cmp r2,$core / is u.break less than Score
As you can see, the errors are almost exclusively in
the comments. Someone with write access to the svn
repository could perhaps take care of that.
Hellwig
I just noticed that the 1972_stuff "as" program generates:
400 MOV #120000,SP
for
core = orig+40000 / specifies beginning of user's core
ecore = core+20000 / specifies end of user's core (4096 words)
[...]
. = orig+400
/ copy in transfer vectors
mov $ecore,sp / put pointer to score in the stack pointer
while the V7 assembler is generating the correct:
400: MOV #60000,SP
I have no idea why it is doing this. The 1972_stuff "nm" program
correctly lists ecore as 60000.
Use the 1972_stuff "as" at your own risk!
Tim Newsham
http://www.thenewsh.com/~newsham/
I wrote a utility for building a cold boot tape and included it in the
tools directory. Its not yet tested so its possible I got the format
wrong... its based on my reading of init at the end of u0.s.
It seems like the permissions in the s2.tar.gz file from the
1972_stuff reflect the original 1ed permission bits (at least the
low order bits do) so this makes restoring the original permissions
fairly easy. Unfortunately the tar doesn't preserve the original
uids. The included "Readme" does have the original uids, so its
possible to recreate the proper uids by hand. If you do so,
my mktape utility should write out the proper uid and mode values.
The use is straightforward:
cd /your/s2/directory
/path/to/mktape.py bin/* etc/*
and you'll get a "tape" file out. I believe you just need the
stuf in bin and etc. The stuff from usr should probably go on
the rk03 disk after cold boot.
Tim Newsham
http://www.thenewsh.com/~newsham/