
The original Unix init system (1972) - vezzy-fnord
https://code.google.com/p/unix-jun72/source/browse/trunk/src/cmd/init.s
======
jhallenworld
So this is pretty neat. From the code we can see that:

If you set the console switches of the PDP-11 to the magic number 173030 init
executes "/bin/sh -" on the console tty (probably a decwriter).

Otherwise it starts /etc/getty on /dev/tty0 - tty8, ttya, and ttyb.

It also starts /etc/dpd ("Dpd is the 201 data phone daemon. It is designed to
submit jobs to the Honeywell 6070 computer via the GRTS interface."),
/usr/mel/da (???) and /usr/demo/dds (???).

When user logs out it's copying the utmp entry to wtmp.

I can see that the init binary is 456 bytes.

It's mounting hard drives /dev/rk1-rk3 on /usr, /sys and /crp. Maybe no
/etc/fstab yet. I guess /dev/rk0 had root.

~~~
voltagex_
>maybe no /etc/fstab yet

Not in that repo [https://github.com/DoctorWkt/unix-
jun72/search?utf8=%E2%9C%9...](https://github.com/DoctorWkt/unix-
jun72/search?utf8=%E2%9C%93&q=fstab) (github mirror picked at random).

I'm not sure what the easiest way to find out when fstab was added would be.

~~~
cremno
Reading man pages and hoping they're correct:

[http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-
current/man5/...](http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-
current/man5/fstab.5)

>The fstab file format appeared in 4.0BSD.

~~~
Someone
I would look in the git repository for Unix:
[https://github.com/dspinellis/unix-history-
repo](https://github.com/dspinellis/unix-history-repo). It isn't guaranteed to
be correct, either, but should have a commit describing its addition that can
be trusted slightly more.

The earlier i can find there without digging deep is BSD 4.4 Lite, a mega-
commit by Rodney Grimes ([https://github.com/dspinellis/unix-history-
repo/commit/d2273...](https://github.com/dspinellis/unix-history-
repo/commit/d22731cac9fabe420b069774896e5e0ba30ee1e5#diff-
ca903a47e79e99bcc3c07fbe0612f1ec))

Being an enormous commit, changes are that it merged in existing stuff.

~~~
cremno
The history section in this man page is correct. Relevant commits in
chronological order:

usr/include/fstab.h: [https://github.com/dspinellis/unix-history-
repo/commit/fd4f9...](https://github.com/dspinellis/unix-history-
repo/commit/fd4f9090882927a06d5b372bd129450058f4e346)

usr/skel/etc/fstab: [https://github.com/dspinellis/unix-history-
repo/commit/fd4f9...](https://github.com/dspinellis/unix-history-
repo/commit/fd4f9090882927a06d5b372bd129450058f4e346)

usr/man/man5/fstab.5: [https://github.com/dspinellis/unix-history-
repo/commit/8591f...](https://github.com/dspinellis/unix-history-
repo/commit/8591f4b1700e44c73ec2359af971421ce0106f76)

------
gexos
Wow this is great... Some history from E. Raymond's page
[http://www.catb.org/esr/writings/taoup/html/ch02s01.html](http://www.catb.org/esr/writings/taoup/html/ch02s01.html)

The original Unix operating system was written in assembler, and the
applications in a mix of assembler and an interpreted language called B, which
had the virtue that it was small enough to run on the PDP-7. But B was not
powerful enough for systems programming, so Dennis Ritchie added data types
and structures to it. The resulting C language evolved from B beginning in
1971; in 1973 Thompson and Ritchie finally succeeded in rewriting Unix in
their new language. This was quite an audacious move; at the time, system
programming was done in assembler in order to extract maximum performance from
the hardware, and the very concept of a portable operating system was barely a
gleam in anyone's eye. As late as 1979, Ritchie could write: “It seems certain
that much of the success of Unix follows from the readability, modifiability,
and portability of its software that in turn follows from its expression in
high-level languages”, in the knowledge that this was a point that still
needed making.

~~~
jhallenworld
The C compiler in this 1972 UNIX is written in an interesting early dialect:

    
    
        1972              Modern
        ----              ------
        foo;              int foo;
        foo 1;            int foo = 1;
        foo[];            int *foo;
        foo[] 1, 2, 3;    int foo[] = { 1, 2, 3 };
        char foo[][];     char **foo;
    

No struct, union, or static. I'm wondering if locals not marked with auto are
static. Also "extern foo" is used as a forward declaration to function or int
foo.

No preprocessor.

~~~
udp

        1972              Modern
        ----              ------
        char foo[][];     char **foo;
    

Really? I see the former quite a bit, and it makes it clearer you mean an
array.

------
luckydude
I agree it's pretty neat. PDP 11 assembler code is the only assembler I can
read like C. I've never come up to speed on x86, I sort of get it but it was
weird in a lot of places so I punted.

I've done other assembler code, not a lot, but I've written swtch() (process
context switch) in 68K and VAX assembly.

Never liked anything as much as the PDP 11. So simple, so clean. The TA who
taught the course where I learned PDP 11 assembly (Ken Witte) was so into it
that he could read octal dumps like it was C. I remember getting him to come
help me debug a problem, I coaxed him to my apartment with a 6 pack of beer,
he looked at some octal and said "right there". Amazing guy but the PDP 11
code was so clean you could do that.

Anyone have a modern instruction set they like as much?

~~~
userbinator
_The TA who taught the course where I learned PDP 11 assembly (Ken Witte) was
so into it that he could read octal dumps like it was C_

I think this is a case of "do anything enough and you'll memorise it" \- I can
mentally disassemble most of the first-page x86 instructions from a hexdump,
although x86 really looks much better in octal (
[http://reocities.com/SiliconValley/heights/7052/opcode.txt](http://reocities.com/SiliconValley/heights/7052/opcode.txt)
), and I still have vague memories of some 6502 instructions from many years
ago.

~~~
joosters
I used to be able to do this for z80. I owned a spectrum and the user manual
had a list of z80 instructions together with their byte code. Lacking an
assembler, my only way of writing code was to hand write the numbers and then
POKE them into memory.

Ah, all those wasted hours writing code, only for it to instantly crash and
lose everything...

~~~
userbinator
The Z80 instruction encoding is also more easily memorised in octal (as are
the 8080 and 8085):

[http://www.z80.info/decoding.htm](http://www.z80.info/decoding.htm)

------
JdeBP
I found M. Toomey's paper more interesting:
[https://www.usenix.org/legacy/event/usenix09/tech/full_paper...](https://www.usenix.org/legacy/event/usenix09/tech/full_papers/toomey/toomey.pdf)

------
jepler
I was most interested to see how the fork syscall works:

    
    
        sys fork
        br new process code
        / old process code continues here
        / r0 contains new process pid
        / c flag set if fork failed
    

so the if(fork() == 0) { child code } else { parent code } of modern fork is
magic right inside the fork syscall (which just has to increment the return
address by the size of one br instruction before returning to the parent)

I guessed some of this from the source, but confirmed more details in
[https://archive.org/stream/bitsavers_attunixUNIedJun72_77658...](https://archive.org/stream/bitsavers_attunixUNIedJun72_7765885/UNIX_Programmers_Manual_2ed_Jun72_djvu.txt)
\-- syscalls were already in section II of the manual at that time, fwiw.

~~~
tonyg
Echoes of this idea still persist in modern systems. For example, from
[http://uninformed.org/?v=1&a=1&t=txt](http://uninformed.org/?v=1&a=1&t=txt)
discussing PowerPC OS X system calls:

"An interesting feature of Mac OS X is that a successful system call will
return to the address 4 bytes after the end of 'sc' instruction and a failed
system call will return directly after the 'sc' instruction. This allows you
to execute a specific instruction only when the system call fails. The most
common application of this feature is to branch to an error handler, although
it can also be used to set a flag or a return value."

A similar idea crops up in ARM's exception/interrupt table, where on exception
N, control passes to the _instruction_ at memory location N*4. Since
instructions are all 4 bytes wide, you usually put a branch instruction in
each slot that jumps to the real handler routine.

~~~
JdeBP
They're not so much echoes as a continuing necessity. System calls in UNIX-
style operating system APIs generally return two integer values, a file
descriptor/character count/ID/whatever and an error code; and because the
twain are largely mutually exclusive the system call mechanism usually
(dependent from the architecture of course) has some way of marshalling that
into one processor register, be it using alternative return addresses or a
flag bit such as the carry flag in the status word.

The OS/2 Control Program API and the Windows NT Native API return the error
codes explicitly from the HLL wrapper functions, the (for example) open file
handle returned from DosOpen() being an integer passed by reference, and their
system call marshalling is thus somewhat different. It helps that calling
conventions such as APIENTRY32
([http://homepage.ntlworld.com./jonathan.deboynepollard/FGA/fu...](http://homepage.ntlworld.com./jonathan.deboynepollard/FGA/function-
calling-conventions.html#APIENTRY32)) lend themselves easily to a treat-the-
stacked-arguments-as-a-structure system, moreover.

I implemented a similar API once, marshalling by-reference system call
arguments through processor registers using a pass-by-value-return scheme.

------
elick
I'd love to see an annotated version of this file explaining what each line
did.

------
api
I propose we replace systemd with this.

~~~
yarrel
It's already been incorporated into systemd. Along with code to fetch today's
xkcd cartoon at startup and a system registry that uses Pig Latin as the
storage format.

~~~
technofiend
That's a terrible lie that besmirches the reputation of systemd. Everyone
knows systemd and etcd store in _Esperanto_! Geez man, get it straight.

------
_RPM
I really appreciate this. I wasn't even though of at the time it was written.
What I mean is that I'm very grateful for computers / electrical engineering.
What a excellent world we live in.

~~~
buffoon
I'm not sure its that excellent a world. We went from this to a mix of massive
broken ISA like x86, piles of firmware, EFI, SecureBoot and then when you
actually organise all the turtles to point the right way, a GDT, IDT to set
up. Ugh.

------
fs111
no QR code generator?

------
transfire
The current system (2015):
[https://github.com/systemd/systemd](https://github.com/systemd/systemd)

~~~
fao_
You seem to be forgetting about all of the other unixes.

Because systemd does not (to my knowledge) support any unix other than Linux,
we can say for certain that OpenBSD, FreeBSD, NetBSD, MINIX 3, Plan 9,
GNU/Hurd, MAC OSX, et al. all do not use systemd. Add to that the fact that
some Linux distributions do not use systemd (Including Slackware, etc), and
you can easily come to the conclusion that systemd is (strictly speaking) in
the minority, and therefore not the main unix init system these days at all.

