[TUHS] Bootstrapping UNIX - how was it done
Clem Cole via TUHS
tuhs at tuhs.org
Tue Mar 24 06:01:14 AEST 2026
A few additions to Noel's comments [we are showing our age here a bit I
suspect].
The M792 (like the FP11 FPU and KT11-C or D MMU were options for the 11/45
or the 11/40). We had several machines without the M792 to save money (
hey we were used to toggling in the bootstrap for years). Like Noel, I
also remember unsoldering and resoldering one that we had to program for a
new disk.
WRT to editors, early UNIXes all used some flavor of ed(1), which was often
extended in different ways depending on the institution. If you go to TUHS
you can find some of them direct from the people that did them, as well as
on USENIX tapes [also an Internet search of the old USENET comp.source
archives are likely to show a few. By the time of the Sixth Edition, you
can find a version of teco(1) in on the USENIX distribution tape from
1979/80 (it's in TUHS). My memory is that it was a hacked version of the
teco from RT11, written in macro11.
WRT to debugging, like Noel, I remember core dumps and the lack of
ptrace(2) in Fifth edition and being glad when Sixth edition included db(1)
for user space. Being a heavy DEC OS shop, DDT was ingrained into our
fingers, and a Unix flavor of it appeared early on in v6. But coming from
TSS, where (like ITS) the command interpreter was the debugger, it was a
weird world for me at first. Of course, we could not (yet) run a debugger
on the kernel itself, so as Noel mentioned, the traditional memory dump was
the fallback when things went south. Using kernel printfs was pretty
standard. One trick we did was we had a printfsw() call, which on the
11/40, 45, and 70, was able to check to set if a bit was set in the console
switch register to decide to print or not (with the 11/34's loss of really
switches, we lost that trick). We could turn on/off different messages,
and for a live system, that was handy. Sometime after V7, a number of us
at different institutions implemented some flavor of a kernel debugger,
often called kdb(1). In small address systems, it could not be very
feature-rich, but by the time of the 68000 workstations, Masscomp's RTU had
a very elegant one, and I'm aware that other folks created fairly elegant
ones as well. Later, when processors became very inexpensive, such as in
the 386-based UNIX systems, a second PC was often used to run the kernel
debugger, and extremely minimal support was needed in the "target." Really
just enough to read/modify the registers, memory, react to a breakpoint,
stop the system, and send the relevant info to the control system
On Mon, Mar 23, 2026 at 12:37 PM Noel Chiappa via TUHS <tuhs at tuhs.org>
wrote:
> > From: Adam Koszek
>
> > How was UNIX bootstrapped in the early days?
>
> How early? The PDP-7? :-)
>
> On _very_ early machines, it was quite common to have to manually enter the
> initial small program for bootstrapping, using the toggle switches on the
> front console (which allowed one to examine and store memory locations), to
> read in the system from wherever it was stored.
>
> Note that _very_ early on, the initial software load would have been on a
> reel of punched paper tape, not read in from the disk. (I think some early
> PDP-11 UNIX versions did that, IIRC.)
>
> Soon after the PDP-11 arrived, it had available a very small bootstrap ROM
> -
> an array of diodes! Diode in = 1, diode out = 0. (I am not making this up!
> Image of one here:
>
> https://gunkies.org/wiki/BM792_ROM
>
> You can read the program off the image! I have actually programmed one of
> those - with a soldering iron!) Most of the -11's I worked with had that,
> or
> a later ROM chip ROM - but not all, and had to be toggled.
>
>
> The software aspect was a whole different world. The DEC-supplied bootstrap
> program (in ROM) loaded block 0 from the disk - which for UNIX contained a
> small elegant program, described here:
>
> https://gunkies.org/wiki/Installing_UNIX_Sixth_Edition
>
> which was prepared too load in the entirety of a normal UNIX-format binary
> file from any place in the file system, and start it. (I used that
> capability
> to load ring network interface diagnostics I wrote.)
>
> From there:
>
> UNIX kernels consists of a number of smallish relocatable binary modules
> which are statically linked into a large object code image; during
> booting,
> that image is loaded into memory and started. After the usual
> initialization,
> the '0th' process (which in V6 has the task of swapping processes in and
> out)
> is hand-crafted; if then 'forks' into two, using the standard UNIX fork()
> system call (which creates a 'clone' of the existing process).
>
> The second process then runs a tiny program (the binary for which is
> built
> into the kernel) which does an 'exec()' system call, to read in and run
> "/etc/init". That process/command then does another fork(), and the child
> process from that exec()'s the shell (command interpreter, in "/bin/sh").
>
> (Which was all very simple, compared to some contemporary operating
> systems.
> To explain how Multics booted _did_ take a book - "Internal Organization of
> Multics System Initialization; Program Logic Manual", AN70:
>
>
> https://bitsavers.mirrorservice.org/pdf/honeywell/large_systems/multics/haley/AN70_Feb75.pdf
>
> In its defense, the exact same magtape could be used to boot _any_ Multics
> system, no matter what its physical configuration; basically, a custom
> kernel
> was linked together during the boot process.)
>
>
> > What editors were used for early B, B+, C and early kernel?
>
> Some version of 'ed', I would expect.
>
>
> > For bootstrapping, some aspects must have been easier: ... But some
> > aspects must have been hard - after hitting some level of complexity
> > with sizable programs, debugging things from the long log of teletype
> > printout must have been interesting
>
> Most programs could be debugged under the OS, and there were tools
> available
> to help with that. In early UNIX versions (before V6; V5 didn't seem to
> have
> ptrace()) debugging was not interactive; the system could produce - on
> demand, or after a fault - a 'core dump' of the process, stored on disk, in
> the file system. 'db' could be used to poke around in that.
>
> Debugging the OS was a whole different trip. I gather that core dumps were
> the usual mechanism at Bell, etc. (At MIT, where we did a lot of OS work,
> to
> add networking, we grumped about that. The _other_ OS's in use in the Tech
> Sq
> building - ITS and TOPS-20 - had debuggers integrated into the OS, so one
> could set breakpoints, single-step them - all symbolically. On UNIX,
> nothing
> doing.)
>
> We should have used printf()'s - maybe the guys at Bell used them, but we
> never did at MIT. (I only started to use them doing retro UNIX OS work,
> after
> I retired.)
>
> From early versions of UNIX (I'm too lazy to check, but I think it started
> at
> the first versions) there was a manual 'core dump' tool. Stop the machine,
> and
> start it (via the front console) at a magic location, and it would write
> the
> entire contents of main memory, along with some key registers, onto a
> magtape. See:
>
> https://minnie.tuhs.org/cgi-bin/utree.pl?file=V6/usr/sys/conf/m40.s
>
> at label "dump:". (Our machine at MIT didn't have a magtape drive, so we
> wrote code to dump it into a reserved partition, on the RK drive we used
> for
> swapping.) With that dump tool, you couldn't see processes that were
> swapped
> out at the time the dump was taken, but it usually saved enough to poke
> around, and thinking hard, work out what had gone wrong.
>
>
> Feel free to ask for details of any part of this!
>
> Noel
>
More information about the TUHS
mailing list