%
% x-kernel v3.3
%
% Copyright (c) 1996,1993,1991,1990  Arizona Board of Regents
%

\subsection{Unix User Level (SunOS/Solaris/OSF/Irix/Linux)}\label{user_level}

The behavior of an {\xk} running as a user task depends on the
``device drivers'' configured into the kernel.  There are two
categories of {\xk} device drivers: those that send real network
packets (e.g., ETHPKT in Linux and IRIXETH in Irix), and those that send
encapsulated network packets (e.g, SIMETH or SIMFDDI).  Real-packet
drivers use platform-specific methods to access network devices, and
are relatively straightforward to configure and use.  (Be sure to see
the manual page for the individual drivers in
Appendix~\ref{prot_specs}.)

\subsubsection{Simulated Drivers}\label{sim_drivers}

Configuring the encapsulated-packet drivers can be confusing.  (We
refer to encapsulated-packet drivers as {\em simulated drivers}, and
instances of {\xk}s using them as {\em simulated hosts}.)  Simulated
drivers sit at the bottom of a protocol stack, just like a standard
device driver.  Instead of sending packets directly to the device,
however, they use the Unix socket interface (and thus the Unix
implementations of UDP and IP) to send and receive packets.  For
example, if you implement IP and UDP {\em within} a user\_level {\xk},
then the UDP packets produced by the {\xk} are, in turn, encapsulated
in real UDP packets.  This means that protocols and programs built on
top of UDP in the {\xk} can only talk to their peers in other {\xk}s;
they cannot communicate with ``real'' versions of those protocols
running on a Unix machine, for example.

Since a user\_level {\xk} with a simulated driver uses a
connectionless UDP socket as its transport mechanism, more than one
such {\xk} can be run on a single workstation.  Because of this
flexibility, the local IP address used by each kernel (the 
{\em simulated IP address}) is decoupled from the IP address of the 
actual workstation on which it runs (the {\em real IP address}).
Configuration files for a user\_level {\xk} must therefore indicate
not only which UDP port should be used by the simulated driver, but
also the binding between the real and simulated IP addresses for each
{\xk}.

Consider the following example ROM files (as described in
Section~\ref{rom_files}) for two user\_level {\xk}s.

\begin{verbatim}
    % cat client/rom

    simeth      port    3050
    #
    #           Sim. IP addr    Real IP addr     Real UDP port
    #
    arp         128.10.5.54     192.12.69.1      3050
    arp         128.10.5.23     192.12.69.1      3051


    % cat server/rom

    simeth      port    3051
    #
    #           Sim. IP addr    Real IP addr     Real UDP port
    #
    arp         128.10.5.54     192.12.69.1      3050
    arp         128.10.5.23     192.12.69.1      3051

\end{verbatim}

\noindent
The {\var simeth} entries indicate the real UDP port number which each
simulated host will use to receive network packets.  A unique port
number must be used for each simulated host running on any given real
processor.  Simulated hosts running on different processors can use
the same port number.  (In this example, the two simulated hosts run
on the same real processor (192.12.69.1) and use different UDP port
numbers: {\var 3051} and {\var 3050}.)  Note that the name of the
ethernet protocol appears exactly as it does in the {\var graph.comp}
file.

For the {\var arp} entries, each line corresponds to a simulated IP
host.  The second field is the simulated IP host number, the third
field is the actual IP host number where the {\xk} runs, and the
fourth field is the {\xk}'s UDP port number.  Note that the simulated
IP host numbers do not necessarily correspond to the real IP address
of the machine on which the simulated host is running.  Since ARP
broadcasts are infeasible for simulated hosts, each {\xk} must be
configured with an {\var arp} entry for each of its peers.

See the manual page in Appendix~\ref{drivers} for more information on
configuring a specific simulated driver.

\subsubsection{Running}\label{running_ul}

As the result of configuring a kernel (Section~\ref{config}), a file
named {\var xkernel} should exist in your build directory.

While in this directory, you should create a sub-directory for each
{\xk} instance to be tested.  For example, if you intend to start up
client and server instances of a user\_level {\xk}, create two
subdirectories, e.g., {\var client} and {\var server}.  In each
subdirectory, create a file named {\var rom}, an example of which can
be copied from {\var /usr/xkernel/user\_level/build/Template}.  The
ROM files should contain configuration information as described in
Section~\ref{rom_files}, and in the man pages for protocols and device
drivers in Appendix~\ref{prot_specs}.

Each simulated host runs as a separate Unix process.  To run multiple
{\xk}s using a windowing user interface, you should start each process
in a separate window.  For each simulated host, open a shell command
window, {\var cd} to the sub-directory that contains that host's 
{\var rom} file (e.g., {\var cd client}) and type {\var ../xkernel}.  
Use {\var DELETE} or {\var CTRL-C} to stop an {\xk}.
