INDRA
Working
Paper
IEN 198
INDRA Note 1041
15th. September 1981
Extended Memory MOS for a UNIX Development Host
Robert Cole
ABSTRACT: This note describes a version of the
RSRE Extended Memory MOS that can be used
with a UNIX development host. The run-
time MOS system design is explained. The
linking and loading phases are described.
Documentation is included in an appendix.
Department of Computer Science
University College, London
Extended Memory MOS for IEN 198
a UNIX Development Host INDRA Note 1152
C O N T E N T S
1. Introduction..............................................2
2. Linking on UNIX...........................................3
3. Loading...................................................5
4. MOS Initialisation........................................7
5. MOS Runtime...............................................7
6. DDT.......................................................7
- 1 - [Robert Cole]
1. Introduction
Recently a version of MOS (Micro Operating System) was
developed at RSRE [1] which enabled the extra memory capacity
of 11/23 and 11/34 computers to be used. The development was
carefully designed to increase the buffer space available to
all processes without adding significant 'context switching'
overheads. A further development at UCL has used the same
design, but for use on a UNIX development host. Standard UNIX
software does not cater for extended memory systems to be
built by users. As a result a new linker was produced, giving
some flexibility to the resulting MOS system. It was decided
to extend the EMMOS system of RSRE by using both USER and
KERNEL addressing modes to provide extra protection and
addressing space.
Figure 1 shows the two address mode maps that are used at
runtime.
page
___________ ___________
| | | stack |
| | |---------|
| I/O | | process |
| page | 7 | buffers |
| | |---------|
| | | data |
|_________| |_________|
| | | process || write
| DDT | 6 | text || protected
|_________| |_________||
| | | |
: : 5 : :
: shared : : : shared :
: buffers : : : buffers :
: : 2 : :
|_________| |_________|
|PCTs+DCTs| 1 |PCTs+DCTs||
| drivers | | drivers || write
| MOS | 0 | MOS || protected
|_________| |_________||
kernel user
Figure 1. Runtime Memory Map
Here the I/O page is only available to the Kernel mode and
both MOS and the process instructions are protected during
process execution. The UNIX object format naturally separates
text (instructions) from data (program variables) so it is
possible to use this in our design. The last page of the user
address space is loaded with the process data at the bottom
and the process stack is created at the top. The full 8K
bytes is allocated so any space left between can be used as
- 2 - [Robert Cole]
Extended Memory MOS for IEN 198
a UNIX Development Host INDRA Note 1152
process private buffer space and managed by the system buffer
management code.
Buffers, which are common to all processes, are set up
above the MOS Kernel and below the processes. Normally the
processes are all loaded in pages 6 and 7, however a very
large process may force this boundary down to page 5. The
size of the MOS Kernel will vary from system to system
depending on the number of processes, the number and nature of
devices, and any other code that is shared between processes.
The MOS Kernel size is rounded up to the next page boundary.
Figure 1 shows 2 pages being used for MOS. The Kernel mode
(and MOS initialisation) stack is placed at the top of the MOS
Kernel space. Thus the shared buffer area is squeezed by code
requirements, however figure 1 shows 4 x 8K of buffer space
(half the virtual address space) and is probably the worst
case. In addition most processes will have some private
buffer space.
During MOS execution the processes are 'swapped in' by
manipulating the Memory Management Unit (MMU) registers.
Apart from loading these registers to swap in a new process
the only other overhead of the extended memory system is the
need to disable the write protection on the MOS Kernel when an
EMT from a process occurs. The protection is re-enabled when
control is returned to the process text.
The remainder of this note describes in detail the linking,
loading, and runtime phases. The appendices contain
documentation on building the extended memory MOS.
2. Linking on UNIX
The standard UNIX linker (ld) is only capable of building a
single 64K byte module. Using a version of ld from MITRE,
which had some modifications for building an overlay, ld was
extended. From the description above it can be seen that the
MOS Kernel is in the address space of each process, but that
the process (text and data) address spaces are mutually
exclusive. This arrangement is most like an overlay system,
with the MOS Kernel as the root. The program, lk (lk for
link), was used to build the root and link in each overlay
separately. Obviously each overlay should be able to access
the root, but not vice versa.
The lk program uses two symbol tables, one for the root,
and one for the current overlay. The overlay symbols are
purged when the overlay definition is complete and the overlay
has been linked. A mechanism was required for MOS to identify
overlay code at runtime for swapping, as well as for them to
- 3 - [Robert Cole]
Extended Memory MOS for IEN 198
a UNIX Development Host INDRA Note 1152
be easily indicated from the C configuration file. The
mechanism chosen is to label each overlay by a tag symbol at
link time. The symbol is given a unique value by the linker.
The symbol itself can be used in C programs, and later in DDT,
to identify a particular overlay (process).
An example command sequence to lk could be:
lk mos.o config.o \
{ _tag1 -n -b 0140000 -e _ent1 proc1.o lib.a }
where
{ ... } defines an overlay
_tag1 is the tag symbol, the leading underscore is
required where the symbol is referenced in C code
-b 0140000 gives the base address at which the overlay
code is to linked (page 6)
-e _ent1 defines the entry address for this overlay
The -b flag is used to relocate the overlay code to the
top end of the address space. The -n flag causes the data to
be relocated to the next page boundary (if possible). At UCL
we use a modified version of cc, called mcc, to build the MOS
load file. Mcc will expand the "{ tagn" to become "{ tagn" -
n -b 014000" and the "}" become "-l }", thus providing
defaults.
The object code output is organised as a number of
subfiles, one for the root, and one for each overlay. These
subfiles are packed into a single output file using the ar (V)
format. Size (I) and nm (I) have been modified to accept
files in ar format and operate on the subfiles.
From the runtime map, fig. 1, it can be seen that DDT is in
the Kernel address space, but at the opposite end to that of
MOS. To achieve this lk recognises the tag "ddt" and marks it
as being in the root (by the magic word) but treats the module
as an overlay for linking purposes.
The normal a.out (V) header has been modified by using the
unused word to include the tag symbol value and the base page
into which the overlay should be swapped. The format is now:
- 4 - [Robert Cole]
Extended Memory MOS for IEN 198
a UNIX Development Host INDRA Note 1152
typedef struct filhdr { /* a.out format header */
int magicw;
#define VMAGIC 0405
#define FMAGIC 0407
#define NMAGIC 0410
#define IMAGIC 0411
#define ROOTMAGIC 0515 /* root file in overlay system */
#define OVNMAGIC 0525 /* overlay with separate I and D */
#define OVFMAGIC 0535 /* overlay with contiguous I and D */
int tsize;
int dsize;
int bsize;
int ssize;
int entrypt;
char tag, page; /* for MOS overlays */
int relflg;
} FILHDR;
3. Loading
Once the complete MOS system has been linked and is ready
in the ar format file; it has to be loaded into the LSI or
PDP-11. To manage the MMU and set up the overlays ready for
swapping a special loader is used in the target computer. At
UCL we load this as an ordinary program using a down-line
loader. The program is then automatically started by the
primary bootstrap and continues as the (secondary) bootstrap.
Each subfile is passed to the secondary bootstrap in two
parts, first the 16 byte a.out header, followed by the text
and data. The a.out header enables the bootstrap to see if
the file contains root code or is an overlay.
If the subfile is a root file (magic word = 0515) it is
loaded into the 1st 6 physical pages and the MMU is not used.
Any symbols associated with the root are placed at the end of
the last physical page (page 30), the amount of space left for
the root symbols is an assembly constant shared between the
virtual bootstrap, virtual MOS and DDT. The page byte in the
a.out header allows loading to begin on any page boundary.
Note that DDT is loaded into page 6 using this mechanism. The
secondary boot operates from the very top of physical page 6
so that DDT should not overwrite this.
If the subfile is an overlay it is loaded above physical
location 0160000. The text and data are loaded contiguously
in 1K byte blocks from UNIX. When the text and data have been
loaded (the a.out header contains the size, this is used as a
check against the amount received) the physical address of the
- 5 - [Robert Cole]
Extended Memory MOS for IEN 198
a UNIX Development Host INDRA Note 1152
top of the 8K process page boundary is calculated. The layout
of a process is shown in Fig. 2.
<--64---><------text-----><------8K------><--symbols-->
bytes bytes
_________________________________._____________________
! H ! ! . ! |
! E ! ! D . ! |
! A ! TEXT ! A . ! |
! D ! ! T . ! |
! E ! ! A . ! |
! R ! ! . ! |
!________!________________!______.________!____________|
! denotes a 64 byte block boundary
Figure 2. Overlay load map.
The a.out header is copied into the first 64 byte block,
this block is used as a control block for the overlay. The
format of this control block is:
typedef struct { /* overlay header block structure */
int magic; /* magic word */
int tsize;
int dsize;
int bsize;
int ssize;
int entry; /* entry address for process */
char tag;
char page; /* same as a.out header up to here */
int used; /* indicates overlay already used */
int memlo; /* address of first free loc in o/v */
int next; /* points to next overlay header */
int par[16]; /* MMU register contents to */
int pdr[16]; /* 'swap' this process in */
} OVERLAY_HEADER;
The base of the 8K page is, of course, the first data byte.
This means there is a hole in the process address space
between the end of the text and the first word of the data.
There is no physical memory assigned to this area. If the
subfile has any symbols these are loaded above the extended
data page. When the data and text have been loaded the bss
area is set to zero, this only occurs at load time. When the
symbols have been loaded the virtual loader calculates the PAR
and PDR register contents for the process by assuming all
unloaded pages are allocated to the low physical memory and
are full (all 8K in use). The loaded pages are given the PAR
and PDR values needed to 'swap' in this process. The first
location in the process private buffer pool is calculated
(size of data + bss + 2 + 0160000) and the PAR contents
- 6 - [Robert Cole]
Extended Memory MOS for IEN 198
a UNIX Development Host INDRA Note 1152
needed to access the next process control block. In this way
the first overlay control block is always at 0160000 and
subsequent overlays can be found by using the chain. The
virtual loader (and MOS) do all address calculation in PAR
content values.
Thus the loader sets up the process, and the necessary MMU
register values, to enable MOS to use the overlay easily.
4. MOS Initialisation
Apart from some modification to the synchronous I/O code
the changes to MOS were in the once only system initialisation
code.
The MMU is enabled as soon as MOS loads the kernel mode
registers to provide the same mapping as though the MMU was
disabled. A window page is used to map into the overlays by
loading a single PAR register with the values provided by the
loader. Any spare physical memory between the last overlay
and the MOS Kernel symbols is divided into 8K pieces and
initialised with a control block. These may be used when two
or more processes share the same text.
The control block used for each overlay means there was no
need to increase the size of the Process Control Table (PCT),
this was convenient as the size is currently 32 bytes.
5. MOS Runtime
As pointed out in [1] it is necessary to use the shared
buffer area for all I/O and especially IORBs. This was the
only change that needs to be made to MOS processes. However,
some processes share routines and data space, these have to be
loaded in the Kernel. All the facilities described in [2] are
available.
The synchronous I/O routines (sin, sout, bin, bout) will
copy data between the process data page and the shared
buffers, if necessary.
6. DDT
The debugging program DDT is always loaded in the extended
MOS. This has the same commands and features as the ordinary
DDT. In addition the following command will 'swap in' a
process, and its symbol table.
- 7 - [Robert Cole]
Extended Memory MOS for IEN 198
a UNIX Development Host INDRA Note 1152
<tag>$l - load an overlay
$l - load the 'normal' address space
The <tag> should be a tag symbol used in linking. If no
tag is given; DDT itself, and the I/O page are mapped in.
Processes can be swapped randomly in DDT, this does not affect
the running of the system.
The only (apparent) facility not readily converted is the
use of single step over RTT and RTI instructions where the
address mode is changed by that instruction.
Note, that when DDT is entered via a break (breakpoint or
single step) PS and SP contain the values in use at the time
of the break, thus are not necessarily the SP of the mode in
which DDT is running. Also when the break occured in user
mode the address space contains the user process, not the I/O
page.
- 8 - [Robert Cole]
Extended Memory MOS for IEN 198
a UNIX Development Host INDRA Note 1152
References
1. Wiseman, S.R., Davies, B.H., Memory Management Extensions
to the SRI Micro Operating System for PDP- 11/23/34/40,
IEN 136, May 1980
2. Cole & Treadwell, MOS User Guide, 2nd Ed.,
Indra Note 1042
- 9 - [Robert Cole]
APPENDIX
This appendix contains an example of building a virtual MOS
system using the normal mechanisms, plus the system
documentation for mcc and lk,
- Appendix 2 - [Robert Cole]
Extended Memory MOS for IEN 198
a UNIX Development Host INDRA Note 1152
Example of Building a vMOS System
The vMOS system is defined in a cnf file in the same way as
an ordinary system. The difference is that the lk 'tag' is
used instead of the entry address. In our example a TCP test
system is built:
extern monitor, control, vcs, tcp, inet, monsl;
PCTE pcts[] {
setpcte("opcon", &control, &dt1i, &dt1o, 300, 0, 0),
setpcte("tcp", &tcp, &cty1, 0, 200, 0, 0),
setpcte("internet", &inet, 0, 0, 300, 0, 0),
setpcte("cstest", &vcs, &cty2, 0, 200, 0, 0),
setpcte("monitor",&monitor, 0, 0, 200, 0, 0),
setpcte("monslave", &monsl, 0, 0, 200, 0, 0),
};
Note that there is no mechanism for automatically loading
complete processes so the Internet and monitoring processes
are explicitly named. For this reason there is a special
version of the TCP process that does not attempt to spawn
those processes.
The commands to mcc must indicate all of the procceses. In
this example a large number of routines are loaded in the
kernel to enable them to be shared amongst processes. In fact
this is to do with the monitoring and all that should be
shared is the name of the routine.
mcc -o vtcptst tcpcnf.c vtcppnt.c monpid.c \
inprnt.c inaddr.c vprintf.o -l1 \
{ control -e opcon opcmds.c -l1 } \
{ vcs -e cstest cstest.o } \
{ monitor -e vmontr -lv } \
{ monsl -e monslave -lv } \
{ tcp -e vtcpm -lv } \
{ inet -e inetm -lv -l1 }
To show how mcc expands this command the actual command
line to lk is shown below. Note that new-lines have been
inserted to improve the clarity of the example.
- Appendix 3 - [Robert Cole]
Extended Memory MOS for IEN 198
a UNIX Development Host INDRA Note 1152
lk -X /ucl/mos/lib/vmos.o -o vtcptst tcpcnf.o vtcppnt.o
monpid.o inprnt.o inaddr.o vprintf.o -l1
{ _control -b 0140000 -n -e _opcon opcmds.o -l1 -l }
{ _vcs -b 0140000 -n -e _cstest cstest.o -l }
{ _monitor -b 0140000 -n -e _vmontr -lv -l }
{ _monsl -b 0140000 -n -e _monslave -lv -l }
{ _tcp -b 0140000 -n -e _vtcpm -lv -l }
{ _inet -b 0140000 -n -e _inetm -lv -l1 -l }
ddtstk.o
{ ddt -b 0140000 -s /ucl/mos/lib/vddt.o }
-l
When converting from an ordinary MOS system to a vMOS
system the 2 major problems are:
1. Different processes that share memory or routines, or
even addresses.
2. Searching libraries so that only the required routines
are built into an overlay, and not included in the
kernel.
- Appendix 4 - [Robert Cole]
LK(I) 15th. September 1981 LK(I)
NAME
lk - link editor for Extended Memory MOS
SYNOPSIS
lk [ { tag ] -sulxnebo name ... [ } ]
DESCRIPTION
Lk is a modification of ld(I) that can build an overlay
system of the type used in the Extended Memory MOS system.
All the features of ld are supported. If no overlays are
defined lk behaves exactly the same as ld, only less
efficiently.
Overlays are defined by enclosing switches and filename
arguments between curly brackets "{}". Each overlay has to
have a name, thus the first argument after every open curly
bracket is taken as the symbol naming that overlay. The
symbol is known as the overlay tag. Each tag is given a
unique value by lk. The overlay definition syntax is:
{ tag -sulxneb name... }
Any arguments not bracketed are used to define the root.
Root arguments may appear in any position between overlay
definitions. All symbols defined in the root arguments are
available to all overlays. Symbols defined in an overlay
are purged when processing of the overlay is complete. Thus
it is not possible to have references between overlays.
Lk produces output in ar(V) format. The root and each
overlay are separate subfiles in the output. Each subfile
is a complete a.out(V) format file with symbols if required.
The default output name is "a.out".
Where symbols are used in the argument list (in -e, -u, and
as the overlay tag) they must be preceded by an underscore
if they are also defined in C programs.
If any argument is a library, it is searched exactly once at
the point it is encountered in the argument list. Only
those routines defining an unresolved external reference are
loaded. If a routine from a library references another
routine in the library, the referenced routine must appear
after the referencing routine in the library. Thus the
order of programs within libraries is important.
Lk understands several flag arguments which are written
preceded by a '-'. Except for -l, they should appear before
the file names.
- 1 -
LK(I) 15th. September 1981 LK(I)
The options suxXneb have a local effect when used within an
overlay definition. If used outside an overlay their effect
is global, but can be overridden by other flags or values.
-s 'squash' the output, that is, remove the symbol
table and relocation bits to save space (but impair the
usefulness of the debugger). This information can also
be removed by strip.
-e The next argument is taken as a symbol defining the
entry address of the overlay or object output.
-u take the following argument as a symbol and enter it
as undefined in the symbol table. This is useful for
loading wholly from a library, since initially the
symbol table is empty and an unresolved reference is
needed to force the loading of the first routine.
-l This option is an abbreviation for a library name.
-l alone stands for 'liba.a', which is the standard
system library for MOS systems. -lx stands for 'libx.a'
where x is any character. A library is searched when
its name is encountered, so the placement of a -l is
significant. The MOS libraries are kept in the MOS
system directory and lk searches this directory for the
libraries defined by the -l switch.
-x do not preserve local (non-.globl) symbols in the
output symbol table; only enter external symbols. This
option saves some space in the output file.
-X Save local symbols except for those whose names
begin with 'L'. This option is used by mcc to discard
internally generated labels while retaining symbols
local to routines.
-n Arrange that when the output file is executed, the
text portion will be read-only and shared among all
users executing the file. This involves moving the data
areas up the the first possible 4K word boundary
following the end of the text. In an overlay this has
the effect of relocating the data to the next memory
page.
-o The next argument is taken the name of the output
file, this overrides the a.out default.
-b The next argument is taken as a number giving the
base address at which linking is to begin. This is used
to relocate overlays above the root. An octal number
- 2 -
LK(I) 15th. September 1981 LK(I)
may be given by using a leading zero (0).
FILES
lib?.a libraries
liba.a MOS system library
lib1.a TCP/IP/OPCON library
lib2.a X25 library
libv.a virtual MOS library
a.out output file
SEE ALSO
as(I), ld(I), ar(I)
BUGS
ORIGIN
MITRE, then Robert Cole at UCL.
- 3 -
MCC(I) 15th. September 1981 MCC(I)
NAME
mcc - C compiler and MOS system builder
SYNOPSIS
mcc [{ tag] [-c] [-p] [-O] [-F] [-S] [-P] file ... [}]
DESCRIPTION
Mcc is the UNIX C compiler which is used to produce a MOS
system load file. Mcc is very similar to cc(I) except that
the command line to the loader (ld(I) or lk(I)) causes a MOS
kernel to be included and MOS system libraries to be
searched.
Arguments whose names end with '.c' are taken to be C source
programs; they are compiled, and each object program is left
on the file whose name is that of the source with '.o'
substituted for '.c'. The '.o' file is normally deleted,
however, if a single C program is compiled and loaded all at
one go.
If curly brackets are used in the argument list an extended
memory system (vMOS) is assumed. For building vMOS systems
mcc will call lk rather than ld for linking. Some expansion
is done by mcc for certain arguments in a vMOS system,
"{ tag" becomes "{ _tag -b 0140000 -n"
"}" becomes "-l }"
Arguments following the -e switch have an underscore
prepended to convert C symbols to overlay symbols, the
overlay tag is similarly treated. The virtual kernel is
loaded, and the DDT segment added to the lk command.
Mcc will compare the modify dates on all source files ('.s'
or '.c') with any object files ('.o') of the same name. If
the object file has a later modify date then the source file
is not compiled.
The following flags are interpreted by mcc. See ld(I) or
lk(I) for load-time flags.
-c Suppress the loading phase of the compilation, and
force an object file to be produced even if only one
program is compiled.
-p Causes a production version of the MOS kernel to be
loaded (mosp.o). The default MOS kernel is mosr.o
which includes DDT.
-O Invoke an object-code optimizer.
- 1 -
MCC(I) 15th. September 1981 MCC(I)
-F Force the compilation of a source file, even if
there is a later object code file available.
-S Compile the named C programs, and leave the
assembler-language output on corresponding files
suffixed '.s'.
-P Run only the macro preprocessor on the named C
programs, and leave the output on corresponding files
suffixed '.i'.
Other arguments are taken to be either loader flag
arguments, or C-compatible object programs, typically
produced by an earlier cc or mcc run, or perhaps libraries
of C-compatible routines. These programs, together with the
results of any compilations specified, are loaded (in the
order given) to produce a loadable MOS system with name
a.out.
FILES
file.c input file
file.o object file
a.out MOS system output
/tmp/ctm? temporary
/lib/c[01] compiler
/ucl/mos/lib/mos[pr].o MOS kernels
/ucl/mos/lib/liba.a MOS system library
/ucl/mos/lib/lib[12v].a MOS utility libraries
SEE ALSO
''Programming in C- a tutorial,'' C Reference Manual,
ld(I), lk(I), load(I)
DIAGNOSTICS
The diagnostics produced by C itself are intended to be
self-explanatory. Occasional messages may be produced by
the assembler or loader. Of these, the most mystifying are
from the assembler, in particular ''m,'' which means a
multiply-defined external symbol (function or data).
BUGS
ORIGIN
UCL - Robert Cole
- 2 -