Xinu7/man/man0/Notes.doc














                  Xinu Programmer's Manual


                         Version 6b






                     (Xinu Is Not Unix)




                         June 1983





          This manual contains  a  description  of  the
     Xinu software.  It has been divided into four sec-
     tions.  The introduction in  section  0  describes
     how to use the Xinu software to compile, download,
     execute, and debug a C program.   Section  0  also
     contains  a  set  of informal implementation notes
     that give the flavor of Xinu.  Section 1 gives the
     details  and  arguments  of cross-development com-
     mands available on the  host  that  cross-compile,
     cross-assemble,  cross-load, download, upload, and
     analyze programs.  Section 2 describes Xinu system
     procedures  that programs call to invoke operating
     system services.  Section 3  describes  procedures
     available  from  the standard libraries.  From the
     programmer's point of view, there is  little  dis-
     tinction   between  library  routines  and  system
     calls.

          As in the UNIX manual, each page describes  a
     command,  system  call or library routine; section
     numbers appear in the  page  header  as  "(digit)"
     following  the  name of the program; within a sec-
     tion all pages are arranged in alphabetical order.
     References  have  the  same form as headers (e.g.,
     "getc(2)" refers to the page for "getc" in section
     2).



                      January 12, 1987





                           - 2 -


_A _S_h_o_r_t _I_n_t_r_o_d_u_c_t_i_o_n _T_o _X_i_n_u _a_n_d _t_h_e _C_r_o_s_s-_D_e_v_e_l_o_p_m_e_n_t _S_o_f_t_w_a_r_e


_H_o_w _t_o _U_s_e _X_i_n_u

     _A_r_c_h_i_t_e_c_t_u_r_e.   Xinu  comes  in  two  parts:  a  cross-
development  environment that runs on the host machine (usu-
ally a Digital Equipment Corp. VAX), and an independent sys-
tem that runs on the microcomputer (usually a Digital Equip-
ment Corporation LSI 11/02).  The microcomputer is connected
to the host over an asynchronous serial line like those used
to connect terminals.  From the point of view of  the  host,
the  microcomputer  is  simply another device that transmits
and receives characters; from  the  point  of  view  of  the
micro,  the host is merely a console terminal that transmits
and receives characters.

     _O_v_e_r_v_i_e_w.  To run a program under Xinu, you create  the
source   file   on  the  host  machine,  and  invoke  cross-
development software to compile and load the  program  along
with the Xinu system.  Once a complete memory image has been
produced, it can be downloaded onto the microcomputer  where
it  executes independent of the host.  During execution, you
invoke a program on the host that captures characters  emit-
ted  by  the micro and displays them on the terminal screen,
and sends characters typed at the  keyboard  to  the  micro.
Thus,  your  terminal  on  the  host appears to be connected
directly to the micro.  If the micro crashes, it can be res-
tarted  without downloading (provided the crash did not des-
troy the program in memory).  To help debug severe  crashes,
the  contents  of  memory  on the micro can be uploaded to a
file on the host where a post-mortem program can analyze the
state and report problems.

     _C_r_o_s_s-_D_e_v_e_l_o_p_m_e_n_t _c_o_m_m_a_n_d_s.  The cross-development sys-
tem  contains  a  C  compiler,  linking  loader, downloader,
uploader, and post-mortem debugger as well as a few  miscel-
laneous  commands.  The details can be found in section 1 of
this manual.  These commands probably  reside  in  the  Xinu
"bin"  directory  on your system; the directory name must be
part of your PATH for you to execute them.  If they are  not
in  directory  /usr/Xinu/bin, consult whoever installed Xinu
to find out the bin directory name and add it to your path.

     _C_o_m_p_i_l_i_n_g _p_r_o_g_r_a_m_s.  The command _c_c_1_1  works  like  the
UNIX  _c_c  command.   It invokes the C cross-compiler, cross-
assember, and cross-loader to translate C  programs  into  a
memory  image.   Like  _c_c, the actions of _c_c_1_1 depend on the
file names passed to it as arguments -- names ending in ".c"
are  assumed  to  be  C  programs,  those ending in ".s" are
assumed to be assember programs, and those  ending  in  ".o"
are  assumed  to  be  previoulsy  compiled  object programs.
Unless you specify  otherwise,  _c_c_1_1  compiles  C  programs,
assembles  assembler  programs, and loads object programs to



Version 6b                1/12/87                          2








produce a memory image in file _a._o_u_t.  Normally, the  memory
image  contains  the  Xinu  operating system along with your
program (you can ask _c_c_1_1 to leave out the operating  system
and just prepare a "stand-alone" program).

     _D_o_w_n_l_o_a_d_i_n_g.  Command _d_o_w_n_l_o_a_d reads  file  _a._o_u_t,  and
loads  the memory image into the microcomputer (it will look
for the memory image in a different file if you instruct  it
to  do  so).   Usually, _d_o_w_n_l_o_a_d is invoked with an argument
"-a5" that  causes  the  microcomputer  to  delay  for  five
seconds before starting execution of the downloaded program.

     _I_n_t_e_r_a_c_t_i_n_g _w_i_t_h _t_h_e _M_i_c_r_o.  The microcomputer on which
Xinu  runs is attached to the host like a peripheral device.
The program _o_d_t "connects" your terminal  to  the  microcom-
puter  by  relaying  characters between the terminal and the
device.  Characters that arrive from the micro are  sent  to
your  terminal,  while characters typed on your keyboard are
sent to the micro.  _O_d_t can be invoked at any time,  but  it
is  most often used just after a _d_o_w_n_l_o_a_d so you can see the
output of the program as it runs.  _O_d_t will halt the  micro-
computer  for you by "breaking" the console line if you type
the 2-character sequence  backslash  (\)  followed  by  null
(CONTROL-@).   To  proceed  again, type uppercase-P (see the
LSI 11 manual for more information on the "odt" mode).

     _D_e_b_u_g_g_i_n_g _a _c_r_a_s_h.  If the program running on the micro
crashes, the cause of trouble may not be easy to spot.  Help
is available from a  post-mortem  debugger,  _p_m.   You  must
first  execute  command  _u_p_l_o_a_d  to copy the complete memory
image from the micro into a file on the host.   By  default,
the  image  file is named _c_o_r_e_1_1.  After the _c_o_r_e_1_1 file has
been created, run command _p_m to cull through  it  and  print
out  the  system  status.   _P_m uses both _c_o_r_e_1_1 and _a._o_u_t to
diagnose the problem (as usual, the actual file names can be
changed if you don't happen to like them).

_A_n _E_x_a_m_p_l_e

     _C_r_e_a_t_e _a _C _p_r_o_g_r_a_m.  For example, here is a  C  program
that  prints the string "Hello world." on the console termi-
nal and exits (_P_r_i_n_t_f is a system (library)  procedure  that
prints  formatted  strings on the console; other system com-
mands are described in sections 2 and 3 of this manual):

            /* example C program in file example.c */
            main()
            {
                    printf("Hello world.\n");
            }


     _C_o_m_p_i_l_e _a_n_d _D_o_w_n_l_o_a_d.  Cross-compile the program, down-
load  it  onto  the  micro, and connect your terminal to the



Version 6b                1/12/87                          1





INTRO(0)          Xinu Programmer's Manual          INTRO(0)


micro with the following commands:

            cc11 example.c
            download -a5
            odt

The cross-compiler will compile the C program, and  load  it
along  with  the  Xinu  system,  leaving  file _a._o_u_t in your
current directory.  The downloader will copy the image  from
_a._o_u_t  into  the micro and start it executing (after a delay
of five seconds).  During downloading, you will see a  count
of  the bytes remaining as blocks are transferred.  Finally,
_o_d_t will connect your terminal to the  micro  (the  5-second
delay leaves time for the VAX to start _o_d_t).  When the micro
begins execution you will see a few Xinu system startup mes-
sages  followed  by  the  program  output.  When all of your
processes complete (in this case, when  the  single  program
terminates), you will see a system termination message.  The
output is:

            Xinu Version 6.09b 3/1/83
            57346 real mem
            21268 avail mem
            clock enabled

            Hello world.

            All user processes have completed.


     _R_e-_r_u_n _t_h_e _p_r_o_g_r_a_m.   To  re-run  the  program  without
downloading the micro again, type:

            \CONTROL-@
            1000G

The 2-character  sequence  backslash  (\)  null  (control-@)
causes  _o_d_t  to  halt the LSI 11 and place it in "ODT" mode.
The LSI 11 responds with an at-sign  prompt.   The  sequence
"1000G"  starts  the  machine  executing  at  location  1000
(octal).  To get out of _o_d_t, kill the process by typing  the
"DELETE" key.  Note that killing _o_d_t does not stop the micro
-- it merely disconnects your terminal.

     _U_p_l_o_a_d _t_h_e _m_e_m_o_r_y.  You may want to see what  processes
are  (were)  running.   To  retrieve  the  memory  image and
analyze it, run the commands:


            upload
            pm

Warning: _u_p_l_o_a_d destroys the contents of memory on the micro
as it executes, so the micro cannot be restarted again after



Version 6b                1/12/87                          2





INTRO(0)          Xinu Programmer's Manual          INTRO(0)


uploading.  Also note that if you interrupt (i.e. kill)  the
uploader and then restart it, the image it retrieves will be
incorrect.

     _I_n_t_e_r_p_r_e_t_i_n_g _p_m.  _P_m reports things  like  whether  the
program  text  has  been changed and the status of each pro-
cess.  If the output from _p_m seems unreasonable,  check  for
the following common errors.  If significant portions of the
program have been changed, it  may  mean  a  stack  overflow
occurred;  totally  meaningless  process  information  often
indicate that the overflow extended into the process  table.
Having  only  one  or two bad process states in an otherwise
meaningful set may indicate that the context switch ended up
with no ready or current processes; this only happens if you
modify the system code or add your own device driver.   When
experimenting  with  device  drivers,  look carefully at the
status of the null process after a crash -- if you  find  it
sleeping, waiting, receiving, or suspended then you probably
have a lower-half driver routine that removes the null  pro-
cess from the current/ready lists.

     _S_y_s_t_e_m _T_e_r_m_i_n_a_t_i_o_n.  Xinu may not always print the sys-
tem  termination  message  even  if all your processes exit,
because it interprets the term "user process" to  mean  "all
processes  except  the  null process." This can be confusing
because the network software  starts  processes  that  never
terminate  (they  continue forwarding frames even if the CPU
is otherwise idle).  Also remember that the tty driver  will
continue  to  echo characters even if there are no processes
running to consume them.

     _H_i_n_t_s _o_n _r_e_s_t_a_r_t_i_n_g.  The LSI 11 ODT command 1000G sets
the program counter to 1000 and starts execution with inter-
rupts _e_n_a_b_l_e_d.  Xinu disables interrupts  immediately  after
it  starts  executing  to avoid being interrupted before the
system is ready.  If an interrupt occurs before the  LSI  11
can execute the first instructon, it may cause the system to
crash (ungracefully).  If your processor gives  you  trouble
with the "G" command, then type the following three lines to
restart Xinu:

            RS/xxxxxx 340
            R7/xxxxxx 1000
            P

The LSI 11 will print  octal  values  in  place  of  xxxxxx.
Note: no carriage return is used after the "P" command (con-
sult the LSI 11 manual for more information).









Version 6b                                                 3








                 _X_i_n_u _I_m_p_l_e_m_e_n_t_a_t_i_o_n _N_o_t_e_s
                 Updated 1/82, 3/82, 11/82.

     These are the notes kept  during  implementation;  they
are  not  designed  as an accurate introduction to Xinu.  In
particular, deferred operations implemented with _p_m_a_r_k  have
disappeared from the book version even though they remain in
version 5.

Some quick ideas:

-  There are multiple processes.

-  A process is known by its process id.

-  The process id is an index into the process table.

-  There are counting semaphores.

-  A semaphore is known by its index in the semaphore table.

-  There is a line time clock.

-  The system schedules processes based on priority.

-  The system supports I/O.

-  For tty I/O characters are queued on  input  and  output.
   The normal mode includes echoing, erasing backspace, etc.

-  There is a frame-level data link  communications  package
   to make a ring of LSI 11's.

-  There is a file system that supports concurrent growth of
   files  without  preallocation; it has only a single-level
   directory sturcture.

-  There is a one-word message passing mechanism.

-  There is support for self-initializing  routines  (memory
   marking) that  makes the system serially reusable without
   requiring the kernel to  explicitly  call  initialization
   routines.

-  Processes can create processes, kill  processes,  suspend
   processes,  restart processes, and change the priority of
   processes.

-  There is no real memory management, but there are  primi-
   tives  for acquiring and returning memory from the global
   pool, and a way to suballocate smaller  pools  of  fixed-
   size buffers.

-  There is a configuration program, config, to  generate  a



Version 6b                1/12/87                          1





NOTES(0)          Xinu Programmer's Manual          NOTES(0)


   Xinu system according to specifications given.

Discussion of implementation:


0. Files.  The system sources are organized as a set of pro-
   cedures.   For  the  most  part, there is a file for each
   system call (e.g., chprio.c for the system call  chprio).
   In  addition  to  the  system call procedures, a file may
   contain utility functions needed  by  that  system  call.
   Files which do not correspond to system calls are:


   Configuration
      The file of device and constant information as  edited
      by  the user to describe the hardware; the config pro-
      gram takes this file and produces  conf.c  and  conf.h
      files.

   conf.h
      Generated constants including I/O and size  constants;
      do not edit directly.

   conf.c
      Generated file of initialized variables; do  not  edit
      directly.

   kernel.h
      General symbolic constants; misc defined macros.

   proc.h
      Process table entry structure declaration; state  con-
      stants.

   sem.h
      Semaphore table entry structure declaration; semaphore
      constants.

   io.hGeneral user-level I/O definitions.

   slu.h
      Serial Line Unit CSR layout; I/O constants for slu's.

   tty.h
      tty line discipline control block, buffers,  excluding
      sizes.

   dlc.h
      line discipline control block for asynchronous  device
      used as network interface.

   disk.h
      disk driver control block.




Version 6b                1/12/87                          2





NOTES(0)          Xinu Programmer's Manual          NOTES(0)


   dtc.h
      Digital Technology Corp. SASI disk interface  hardware
      register layouts.

   xebec.h
      Xebec Corp. SASI disk controller register layouts.

   frame.h
      Xinu ring network frame format definitions.

   bufpool.h
      Buffer pool constants and format.

   mark.h
      Memory marking table declarations.

   mem.h
      Memory management free list format declarations.

   ports.h
      Definitions for communications ports (queued interpro-
      cess rendevous points).

   sleep.h
      Definitions for real-time delay software.

   dir.h
      Layout of disk directory block.

   iblock.h"
      Layout of index block (i-block).

   file.h
      Definitions of variables and  constants  used  by  the
      local file system routines.

   q.hq data structure declaration (see below); defined mac-
      ros for q predicates.

   queue.c
      q manipulation routines.

   resched.c
      Almost  the  inner  most  routine  (rescheduler).   It
      selects  the  next process to run from the ready queue
      and fixes up the state.  Calls ctxsw  to  switch  con-
      texts.

   cxtsw.s
      The routine that actually changes the  executing  pro-
      cess  into  another one.  A very small piece of assem-
      bler code with only  one  trick:  when  a  process  is
      saved,  the  execution address at which it restarts is
      actually the instruction following the call to ctxsw.



Version 6b                1/12/87                          3





NOTES(0)          Xinu Programmer's Manual          NOTES(0)


   lowcore.s
      The loaded version of the low part of  memory  (inter-
      rupt  vectors).  All interrupt vectors are initialized
      by  the  loader  to  point  to  panic  routines,   and
      overwritten for valid devices at startup.

   ioint.s
      I/O interrupt dispatchers.

   startup.s
      Actual entry point (start) with code to set up C  run-
      time environment and call high-level initialization.

   initialize.c
      All external  (global)  variables,  the  null  process
      (process 0, see below), and the high-level system ini-
      tialization routine (e.g., to craft the process  table
      entry for process 0).

   userret.c
      The routine to which user processes return (i.e. exit)
      if they ever do.  Care should be taken so that userret
      never exits; it must kill the  process  that  runs  it
      because there is no legal return frame on the stack.

   sizmem.s
      Utility procedure to size main memory.



1. Process states.  Each process has a state  given  by  the
   pstate  field  in  the  process  table  entry.  The state
   values are given by symbolic  constants  PRxxxx.   PRFREE
   means  that  the  process entry is unused.  PRREADY means
   that the process is linked into the  ready  list  and  is
   eligible  for  the CPU.  PRWAIT means that the process is
   waiting on a semaphore (given  by  psem).   PRSUSP  means
   that  the  process  is  in  hibernation; it is not on any
   list.  PRSLEEP means that the process is in the queue  of
   sleeping  processes waiting to be awakened.  PRCURR means
   that the process is (the  only  one)  currently  running.
   The  currently  running process is NOT on the ready list.
   In addition to the actual state, there is a "mark"  field
   (pmark)  which  indicates  pending state changes.  PMDEAD
   indicates that the process has been killed and should  be
   removed  as  soon  as it reaches the ready queue.  PMSUSP
   indicates that the process has been suspended and  should
   move  to  the  suspended  state as soon as it reaches the
   ready queue.  PMNONE indicates no pending action.

2. Semaphores.  Semaphores reside in the array semaph.  Each
   entry  in  the array corresponds to a semaphore and has a
   count (scount), and state (sstate).  The state  is  SFREE
   if  the  semaphore  slot  is  unassigned,  SUSED  if  the



Version 6b                1/12/87                          4





NOTES(0)          Xinu Programmer's Manual          NOTES(0)


   semaphore is in use.  If the count is -p then the  sqhead
   and  sqtail  fields  point to a FIFO queue of p processes
   waiting for the semaphore.  If the count is nonnegative p
   then  no  processes are waiting.  More about the head and
   tail pointers below.

3. Suspension.  Suspended processes are forbidden from using
   the CPU.  They may remain on semaphore/sleep queues until
   they are to be moved to  the  ready  queue.   A  call  to
   ready(p),  where  p  has  been marked suspended, will NOT
   place it on the ready queue.  It will merely result in  p
   being  placed  in the suspended state.  Suspending a pro-
   cess that is already on the ready queue will  remove  it.
   Suspending the current processes forces it to give up the
   CPU.

4. Sleeping.  When a  process  calls  sleep(n)  it  will  be
   delayed  n seconds.  This is achieved by placing the pro-
   cess on a queue of jobs ordered by wakeup time and relin-
   quishing  the  CPU.   Every 60th of a second, an external
   line-time clock will interrupt the CPU and cause a  clock
   interrupt routine to be called.  To avoid extra overhead,
   5 such interrupts are ignored before  one  is  processed.
   Thus,  the  granularity  of  clock  counts  is  1/10 of a
   second.  The interrupt  handler  maintains  a  clock  and
   moves processes back to the ready queue when their wakeup
   time has been reached.  Notice that  a  process  may  put
   itself, but no one else, to sleep.

5. Queues and ordered lists.  There is  one  data  structure
   for  all heads, tails, and elements of queues or lists of
   processes: q[].  The first  NPROC  entries  in  q  (0  to
   NPROC-1) correspond to the NPROC processes.  If one wants
   to link process i onto a queue or  list,  then  one  uses
   q[i].qnext  and  q[i].qprev  as  the forward and backward
   pointers.

   The remaining entries in q are used  for  the  heads  and
   tails  of  lists.  The integer nextqueue always points to
   the next available entry in q to assign.  When initialize
   builds  the  heads and tails of various lists, it assigns
   entries in q sequentially.  Thus, the sqhead  and  sqtail
   fields  of a semaphore are really the indices of the head
   and tail of the list in q.  The advantage of keeping  all
   heads  and  tails  in  the  same  data  structure is that
   enqueueing, dequeuing, testing  for  empty/nonempty,  and
   removing  from the middle (eg., when a process is killed)
   are all handled by  a  small  set  of  simple  procedures
   (files queue.c and q.h).  An empty queue has the head and
   tail pointing to each other.  Since all real  items  have
   index  less  than  NPROC, testing whether a list is empty
   becomes trivial.  In addition to FIFO queues, q also con-
   tains  ordered lists based on an integer kept in the qkey
   field.  For example, processes are inserted in the  ready



Version 6b                1/12/87                          5





NOTES(0)          Xinu Programmer's Manual          NOTES(0)


   list  (head at position q[rdylist]) based on their prior-
   ity.  They are inserted in the sleep list based on wakeup
   time.   Ordered  lists are always in ascending order with
   the inserted item stuck in BEFORE  those  with  an  equal
   key.   Thus,  processes  are  removed from the ready list
   from the tail to get the highest priority process.  Also,
   processes  of  equal  priority are scheduled round robin.
   Since the sleep queues are serviced from the smallest  to
   largest  keys,  items  are  removed  from the head of the
   queue (equal keys do not matter for sleeps).

6. Process 0.  Process 0 is a null process  that  is  always
   available  to  run  or is running.  Care must be taken so
   that process 0 never executes code that could  cause  its
   suspension  (e.g. it cannot wait for a semaphore).  Since
   Process 0 may be running during  interrupts,  this  means
   that interrupt code may never wait for a semaphore.  Pro-
   cess 0 initializes the system,  creates  the  first  user
   process,  starts  it executing the main program, and goes
   into  an  infinite  loop  waiting  until  an   interrupt.
   Because its priority is lower than that of any other pro-
   cess, the null process loop executes only when  no  other
   process  is  ready.   It  uses  a pause instruction while
   waiting to avoid taking bus cycles just in case dma  dev-
   ices are running.
































Version 6b                1/12/87                          6