.sp
.ul
UNIX
.pg
The source and object programs for UNIX are kept in
.ul
/usr/sys
and three subdirectories therein.
The main directory contains several files with names ending
in ".h"; these are header files which are
picked up (via "#include ...")
as required by each system module.
The files lib1 and lib2 are libraries (archives)
of (almost) all the object programs
in the system.
Lib1 is made from the source programs in the
subdirectory
.ul
ken;
lib2 is made from the programs in subdirectory
.ul
dmr.
The latter consists mostly of the device drivers
together with a few other things,
the former is the rest of the system.
.pg
Subdirectory
.ul
conf
contains the programs which control
device configuration of the system.
.ul
Low.s
specifies the
contents of the interrupt vectors;
conf.c contains the tables which relate device numbers
to handler routines.
A third program, mch.s,
contains all the
machine-language code in the system.
It contains conditional-assembly
flags which control whether the system will run on
an 11/40 or /45, and whether it supports
the 11/45 floating-point unit.
It is quite long, but almost all of it
is concerned
with recovering after a stack violation in an 11/40.
.pg
To recreate the system,
compile conf.c and move the output to /usr/sys/conf.o.
Assemble low.s and mch.s
and move the output to /usr/sys/low.o and
mch.o respectively.
Then change to
/usr/sys,
and load the whole system:
.pg
	ld -x low.o mch.o conf.o lib1 lib2
.pg
For convenience, this command line has been placed
into /usr/sys/ld.
.pg
When the
.ul
ld
is
done, the new system is present as
.ul
a.out.
It can also be tested by putting it on tape
(tp-I) and using tboot or mboot,
or directly using uboot (boot procedures-VIII).
When you have satisfied yourself that it works,
it should be renamed /usr/sys/unix
so that programs like ps (I)
can use it to pick up addresses in the system.
.pg
To install a new device driver,
compile it and place the object in lib2 if necessary.
(All the device drivers distributed with
the system are already there.)
The device's
interrupt
vector must be entered in
low.s.
This involves placing a pointer to a callout routine
and the device's priority level in the vector.
As an example, consider installing the interrupt vector
for DC11 number 2.
Its receiver interrupts at location 320 and the transmitter at 324,
both at priority level 5.
Then low.s has:
.pg
	. = 320^.
	dcin; br5+2
	dcou; br5+2
.pg
First, notice that the entries in low.s must be in order,
since the assembler does not permit moving the
location counter "." backwards.
The assembler also does not permit assignation of
an absolute number to ".", which is the
reason for the ". = 320^." subterfuge;
consult the Assembler Manual for the meaning of the notation.
If a constant smaller than 16(10) is added to the
priority level,
this number will be available as the first argument of the interrupt routine.
This strategem is used when
several similar devices share the same interrupt routine.
.pg
At the end of low.s,
add
.pg
		.globl	_dcrint
	dcin:
		jsr	r0,call; _dcrint
.pg
		.globl	_dcxint
	dcou:
		jsr	r0,call; _dcxint
.pg
The
.it call
routine
saves registers as required and makes a C-style
call on the actual interrupt routine (here _dcrint and _dcxint)
named after the jsr instruction.
When the routine returns,
.it call
restores the registers and performs an
rti instruction.
.pg
To install a new device thus requires
knowing the name of its interrupt routines.
These routines are in general easily found
in the driver; they typically end in the letters
"int" or "intr."
Notice that external names in C programs have an
underscore "_" prepended to them.
.pg
The second step which must be performed to add a new device is
to add it to the configuration table
/usr/sys/conf/conf.c.
This file contains two subtables,
one for block-type devices, and one for character-type devices.
Block devices include disks, DECtape, and magtape.
All other devices are character devices.
A line in each of these tables gives all the information
the system needs to know about the device handler;
the ordinal position of the line in the table implies
its major device number, starting at 0.
.pg
There are four subentries per line in the block device table,
which give its open routine, close routine, strategy routine, and
device table.
The open and close routines may be nonexistent,
in which case the name "nulldev" is given;
this routine merely returns.
The strategy routine is called to do any I/O,
and the device table contains status information for the device.
.pg
For character devices, each line in the table
specifies a routine for open,
close, read, and write, and one which sets and returns
device-specific status (used, for example, for stty and gtty
on typewriters).
If there is no open or close routine, "nulldev" may
be given; if there is not read, write, or status
routine, "nodev" may be given.
This return sets an error flag and returns.
.pg
The above discussion is admittedly rather cryptic
in the absence of a general
description of system I/O interfaces.
All we can suggest is that sample configuration
tables be examined.
.pg
The final step which must
be taken to install a device is to make a special for it.
This is done by mknod (VIII), to which you must specify the
device class (block or character),
major device number (relative line in the configuration table)
and minor device number
(which is made available to the driver at appropriate times).
