\documentclass[table, usenames]{beamer}
\usetheme{lankton-keynote}
%\usetheme{CambridgeUS}

\usepackage{soul}
\usepackage{xcolor}

\usepackage{amsmath}
\usepackage{amssymb}

\usepackage{datetime}
\usepackage{enumerate}
\usepackage{fontspec}

\usepackage{graphicx}
\usepackage{listings}
\usepackage{makecell}
\usepackage{multicol}
\usepackage{multirow}

\usepackage{soul}
\usepackage{tabularx}
\usepackage{textcomp}
\usepackage{tikz}
\usetikzlibrary{arrows,arrows.meta,automata,calc,decorations.pathmorphing,backgrounds,positioning,fit,scopes,shapes.multipart,shapes.arrows,quotes}

\usepackage{drawstack}
\usepackage{xltxtra}

% define setlistspacing that works w/beamer (would love enumitem...)
\makeatletter
\newcommand{\setlistspacing}[2]{\def\@ld{#1}\expandafter\def\csname
@list\romannumeral\@ld \endcsname{\leftmargin\csname
leftmargin\romannumeral\@ld \endcsname
              \topsep    #2
              \parsep    0\p@   \@plus\p@
              \itemsep   #2}}
\makeatother

\defaultfontfeatures{Scale=MatchLowercase}
\setmainfont{Gentium Book Basic}
\setmonofont{JetBrainsMono Nerd Font} [
  Scale = 0.85,
  ]

\definecolor{commandlinebackground}{gray}{0.35}
\definecolor{commandlineforeground}{gray}{1.00}
\definecolor{commandpromptforeground}{gray}{0.75}

\lstset{language=c++,
  numbers=none,
  numberstyle=\tiny,
  stepnumber=1,
  numbersep=7pt,
  frame=none,
  framerule=0.8pt,
  framesep=5pt,
  captionpos=b,
  showstringspaces=false,
  showlines=true,
  literate={-}{{\texttt{-}}}1{--}{{\texttt{-{}-}}}2{---}{{\texttt{-{}-{}-}}}3,
  basicstyle=\ttfamily,
  rulecolor=\color{black}
}

% ----- Command-line "language" definition for listings -----
\lstdefinelanguage{cline}
{
}
\lstnewenvironment{commandline}[1][]
{\lstset{language=cline,numbers=none,frame=none,backgroundcolor=\color{commandlinebackground},basicstyle=\color{commandlineforeground}\ttfamily,nolol,#1}}
  {}

\title{CIS 310 Operating Systems}
\subtitle{Week 2:  What is a Computer?}
\author{Dr. Brian C. Ladd}

\tikzset{
  abstractCPU/.pic={
    code={{[y=-1.0cm]
      \node[shape=rectangle, minimum width=5.0cm, minimum
      height=5.0cm, draw] (-cpu) {};

      \draw (-1.4, 2) node {\tiny Registers};
      \foreach \i [evaluate= \i as \y using (2 - (\i + 1)*0.5)] in {0,1,...,3} {
        \draw (-1.4, \y) node[draw, shape=rectangle, minimum width=1.5cm, minimum
        height=0.5cm] (reg\i) {};
      }

      \draw (-1.4, -0.5) node {...};

      \foreach \i [evaluate= \i as \y using (2 - (\i + 1)*0.5)] in {5,6,7} {
        \draw (-1.4, \y) node[draw, shape=rectangle, minimum width=1.5cm, minimum
        height=0.5cm] (reg\i) {};
      }
      \draw (reg6) node[shape=coordinate] (idr) {};
      \draw (reg7) node[shape=coordinate] (pc) {};

      \draw (idr) + (1.25, 0) node[align=left] {\texttt{idr}};
      \draw (reg7) + (1.25, 0) node[align=left] {\texttt{pc}};

      \draw (1, 1) node[shape=rectangle, minimum width=2cm, minimum
      height=1.25cm, draw] (-control) {Control};
      \draw (1, -0.25) node[shape=rectangle, minimum width=2cm, minimum
      height=1.25cm, draw] (-alu) {ALU};

      \coordinate (-out) at ($(-cpu.east) + (0, 1.25cm)$);
      \coordinate (-in) at ($(-cpu.east) + (0, -1.25cm)$);
    }}
  }
}
\tikzset{
  RAM/.pic = {
    code = {{[y=-1.0cm]
       \draw (-1, -0.5) node[anchor=south west,shape=rectangle,minimum width=2cm,
       minimum height=6cm,draw] (-ram) {};
       \foreach \a/\y in
       {0x0000/5.0,0x0001/4.5,0x0002/4.0,0x0003/3.5,0x0004/3.0} {
         \draw (0, \y) node[align=right,anchor=east]{{\tiny \texttt{\a}}}
               (0.25, \y) node[draw, shape=rectangle,minimum width =
               0.5cm, minimum height=0.5cm] {};
       }

       \draw (0.25, 2.5) node {...};

       \foreach \a/\y in
       {0xFFFB/2.0,0xFFFC/1.5,0xFFFD/1.0,0xFFFE/0.5,0xFFFF/0.0} {
         \draw (0, \y) node[align=right,anchor=east]{{\tiny \texttt{\a}}}
               (0.25, \y) node[draw, shape=rectangle,minimum width =
               0.5cm, minimum height=0.5cm] {};

      \coordinate (-out) at ($(-ram.west) + (0, 1.5cm)$);
      \coordinate (-in) at ($(-ram.west) + (0, -1.5cm)$);
       }
    }}
  }
}

\begin{document}
\begin{frame}
  \titlepage
\end{frame}

\begin{frame}
  \frametitle{Outline}
  \tableofcontents
\end{frame}


\section{Computer Architecture}

\begin{frame}
  \frametitle{Computer Architecture}
  \begin{definition}
    Your machine is a \emph{digital}, \emph{binary},
    \emph{general-purpose} device.
  \end{definition}

  \begin{description}
  \item<2->[digital] composed of discrete units (digits).
  \item<3->[binary] using base 2, the set of $\{0, 1\}$.
  \item<4->[general purpose] capable of interpreting \emph{encoded}
    data. Given enough bits, anything can be encoded.
  \end{description}

  \begin{definition}<5->
  Our \emph{stored-program} computers can store and interpret
  \textbf{instructions} on how to interpret bits in memory.
  \end{definition}
\end{frame}

\subsection{The main parts}
\begin{frame}
  \frametitle{von Neumann Architecture}

  \begin{itemize}
  \item A single, unified \emph{memory}.
  \item A single$^*$ processor.
  \item A bidirectional connection between them.
  \end{itemize}
\end{frame}

\begin{frame}
  \frametitle{Parts}
  \begin{tikzpicture}[scale=0.5]
    \draw (0, 5) pic[name=CPU] {abstractCPU} {};
    \draw (0, 11) node {CPU};
    \draw (15, -1) pic[name=RAM] {RAM} {};
    \draw (15, 11)node {RAM};
    \draw (9, 4) node[shape=double arrow,draw,minimum height=4cm] {Memory Bus};
  \end{tikzpicture}
\end{frame}

\begin{frame}[fragile]
  \frametitle{The Cycle}

\begin{lstlisting}
  while (not halted):
    fetch instruction from RAM[pc] into idr
    decode idr
    execute
\end{lstlisting}
\end{frame}

\section{Hardware Support for an OS}

\begin{frame}
  \frametitle{What Only Hardware Can Do}
  \begin{itemize}
  \item<+-> Interrupts
  \item<+-> Privilege Bit
  \item<+-> System Calls
  \item<+-> Address Translation
  \item<+-> Atomic Instructions
  \end{itemize}
\end{frame}

\subsection{Privilege Bit}

\begin{frame}
  \frametitle{Kernel/User Mode}
  \begin{itemize}
  \item CPU \emph{status register} has a \emph{privilege bit}\\
    \lstinline|0| $\Rightarrow$ \textbf{user} mode\\
    \lstinline|1| $\Rightarrow$ \textbf{kernel} (system) mode
  \end{itemize}
\end{frame}

\begin{frame}
  \frametitle{User Mode}
  \begin{itemize}
  \item All addresses are \emph{translated} by the hardware according
    to policy set by the operating system.
  \item Direct interaction with certain parts of memory is
    \emph{forbidden}, \emph{e.g.} memory-mapped device ports, OS data
    structures, interrupt service vector, OS code, hardware timer
    settings.
  \item Certain CPU instructions are \emph{forbidden} and will
    generate an \emph{interrupt} if they are attempted.
  \item \textbf{Limited Direct Execution}
  \end{itemize}
\end{frame}

\begin{frame}
  \frametitle{Kernel Mode}
  \begin{itemize}
  \item Permit all the forbidden stuff.
  \item \textbf{Direct Execution}
  \end{itemize}
\end{frame}

\begin{frame}
  \frametitle{Switching?}
  How can your program write something to a file if it lives in
  \emph{user} mode and only the \emph{system} mode can interact with
  devices that have files on them?

  \pause
  \textbf{Good Question}

  We will answer it in a minute.
\end{frame}

\subsection{Interrupts}
\begin{frame}
  \frametitle{Next Instruction}
  How does the CPU select the \emph{next} instruction to execute?

  \pause
  The value in the \lstinline|pc| register
  \begin{itemize}
  \item[] \lstinline|fetch|
  \item[] \lstinline|decode|
  \item[] \lstinline|execute|
  \end{itemize}

  \pause
  What if some \emph{hardware} or even some \emph{software} needs
  immediate service?

  \pause
  An \textbf{Interrupt}
\end{frame}

\begin{frame}
  \frametitle{Taking an Interrupt}

  \begin{itemize}
  \item Before \lstinline|fetch|: check for pending interrupt.
  \item With highest priority pending interrupt
    \begin{itemize}
    \item Set \emph{privilege bit}
    \item Save \emph{context} of user program on \textbf{k-stack}
    \item Use \emph{interrupt number} is index into \lstinline|ISV|:
      jump to the address.
    \item Run \emph{interrupt service routine} using normal
      \lstinline|fetch-decode-execute| cycle (but with privilege).
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}
  \frametitle{A Process in RAM}
  \tikzstyle{RAMBox} = [right, draw, thick, fill=black!50, minimum height=0.5cm, minimum width = 7.0cm, rectangle]
  \tikzstyle{pBox} = [right, draw, thick, fill=red!50!black!80, minimum height=0.5cm, minimum width = 1.25cm, rectangle]

  \tikzstyle{jTableBG} = [right, draw, thick, minimum height = 0.5cm, minimum width=1.25cm]

  Machine RAM with a process, \lstinline|p| in it.

  \begin{tikzpicture}
  \draw (0,0) node[RAMBox] (RAM) {};
  \draw node[below=0.0cm of RAM] (title) {RAM};

  \draw (2.7,0) node[pBox, minimum width=1.25cm] (p) {};
  \draw [decorate,decoration={brace,amplitude=5pt},xshift=0pt,yshift=2pt]
  (p.north west) -- (p.north east) node [midway,yshift=0.3cm] {$p$};

  \draw  (0,0) node[fill=black!90,jTableBG] (intDispatch) {};
  \draw [decorate,decoration={brace,amplitude=5pt,mirror},xshift=0pt,yshift=-2pt]
  (intDispatch.south west) -- (intDispatch.south east) node
  [midway,yshift=-0.3cm] {\tiny hardware};

  \draw  (5.75, 0) node[fill=black!70!green,jTableBG] (os) {};
    \draw [decorate,decoration={brace,amplitude=5pt,mirror},xshift=0pt,yshift=-2pt]
  (os.south west) -- (os.south east) node
  [midway,yshift=-0.3cm] {\tiny operating system};
\end{tikzpicture}

\pause
Looking more closely at hardware handled memory.

\begin{tikzpicture}
  \draw (0,0) node[RAMBox] (RAM) {};
  \draw node[below=0.0cm of RAM] (title) {RAM};

  \draw (2.7,0) node[pBox, minimum width=1.25cm] (p) {};

  \draw  (0,0) node[fill=black!90,jTableBG] (hardwareRam) {};
  \foreach \i [evaluate= \i as \x using 0.05*\i] in {1,...,9} {
    \draw (0, 0) ++(\x, -0.125) rectangle +(0.05, 0.25);
  }
  \coordinate (isv) at (0.15, 0.15);

  \foreach \i [evaluate= \i as \y using 0.08*\i] in {0,1,...,4} {
    \draw (1.0, -0.2 + \y) rectangle +(0.08, 0.08);
  }

  \draw (0.4,0.6) node (int) {\tiny \texttt{ISV}};
  \path[-] (int.south) edge (isv);

  \draw (0.5,-0.5) node (kstack) {\tiny \texttt{k-stack}};
  \path[-] (kstack.north) edge (0.95, 0.0);

  \draw  (5.75, 0) node[fill=black!70!green,jTableBG] (os) {};
\end{tikzpicture}

\pause
Taking an interrupt.

\begin{tikzpicture}
  \draw (0,0) node[RAMBox] (RAM) {};
  \draw node[below=0.0cm of RAM] (title) {RAM};

  \draw (2.7,0) node[pBox, minimum width=1.25cm] (p) {};

  \draw  (0,0) node[fill=black!90,jTableBG] (hardwareRam) {};
  \foreach \i [evaluate= \i as \x using 0.05*\i] in {1,...,9} {
    \draw (0, 0) ++(\x, -0.125) rectangle +(0.05, 0.25);
  }

  \fill  (0.2,-0.125) rectangle +(0.05, 0.25);

  \coordinate (takenInterrupt) at (0.225, 0.125);

  \draw  (5.75, 0) node[fill=black!70!green,jTableBG] (os) {};
  \draw  (os.north) node[anchor=north west,fill=black!50!green,draw,fill,minimum
  width=0.5cm, minimum height=0.5cm,font={\fontsize{6pt}{6}\selectfont}] (handler) {IH};

  \draw (takenInterrupt) edge [bend left, -Stealth] (os.north);
\end{tikzpicture}
\end{frame}

\begin{frame}
  \frametitle{Returning from an Interrupt}

  \begin{itemize}
    \item[] ~
    \begin{itemize}
    \item Ensure the context of appropriate user \emph{process} is on
      \lstinline|k-stack|.
    \item Unset \emph{privilege bit}
    \item Restore context from \lstinline|k-stack|.
    \end{itemize}
  \item Restart instruction pointed to by \lstinline|pc| for user
    code.
  \end{itemize}
\end{frame}

\begin{frame}
  \frametitle{Big Idea}
  The idea of a \textbf{jump table} (or \emph{service vector}) is very
  useful in building a flexible interface.

  \begin{itemize}
  \item Outside world provides a number indicating an event or
    request.
  \item Inside, we have an array of pointers at code. Indexing by
    event gives us the code to run.
  \item \textbf{Interface} because we publish the list of numbers we
    expect for different events (or accommodate such a list provided
    by a hardware manufacturer).
  \item \textbf{Flexible} because we can change how we handle any
    given event just by providing code and pointing at it.
  \end{itemize}
\end{frame}

\subsection{System Calls}

\begin{frame}
  \frametitle{System Call}
  \begin{itemize}
  \item<+-> Can we avoid building a \emph{new} system for user code to
    do system things?
  \item<+-> \textbf{Interrupt} system already promotes from \emph{user}
    $\Rightarrow$ \emph{system} mode.
  \item<+-> Still do not want to have user code executing in system mode
    (\textbf{Never} trust users. \textbf{Never!})
  \item<+-> Can the OS leverage this to permit \emph{user} mode software
    to \emph{request} privileged services from the OS.
  \item<+-> \textbf{System Call} or a \emph{software interrupt}.
  \end{itemize}
\end{frame}

\begin{frame}
  \frametitle{Handling a System Call}
  \begin{itemize}
  \item<+-> OS knows what kind of \emph{hardware} interrupt happened
    by the \emph{interrupt number}.
  \item<+-> User code has to ask for many \textbf{different} actions
    from the OS.
  \item<+-> Yet \lstinline|syscall| always generates the same
    interrupt.\\
    How can the \emph{user} communicate the function they wish to
    request?
  \end{itemize}
\end{frame}

\begin{frame}
  \frametitle{System Call Function Numbers}

  The OS can define that certain registers, in addition to being saved
  during a \lstinline|syscall|, will also be read or written by the
  OS.

  The registers provide the function number and \emph{parameters} for
  the \lstinline|syscall|.

  How does the OS call the right code for a given function?
\end{frame}

\begin{frame}[fragile]
  \frametitle{Program Writes a String}
\begin{lstlisting}[language={[x86masm]assembler}]
  mov   rax,  1   ; system call number for write
  mov   rdi,  1   ; param 1: file descriptor (FD) number.
                  ; FD 1 is stdout
  mov   rsi, msg  ; param 2: address of string
  mov   rdx, len  ; param 3: length of string
  syscall         ; trap into OS kernel
\end{lstlisting}
  By Linux convention
  \begin{itemize}
  \item [\texttt{rax}] is the function number\\
    and for write
  \item [\texttt{rdi}] is a file descriptor
  \item [rsi] points to an array of char
  \item [rdx] is length of array of char
  \end{itemize}
\end{frame}

\begin{frame}
  \frametitle{Requesting Privileged Access}
  \tikzstyle{RAMBox} = [right, draw, thick, fill=black!50, minimum height=0.5cm, minimum width = 7.0cm, rectangle]
  \tikzstyle{pBox} = [right, draw, thick, fill=red!50!black!80, minimum height=0.5cm, minimum width = 1.25cm, rectangle]

  \tikzstyle{jTableBG} = [right, draw, thick, minimum height = 0.5cm, minimum width=1.25cm]

  What happens when our program makes a system call?

\begin{tikzpicture}
  \draw (0,0) node[RAMBox] (RAM) {};
  \draw node[below=0.0cm of RAM] (title) {RAM};

  \draw (2.7,0) node[pBox, minimum width=1.25cm] (p) {};

  \draw  (0,0) node[fill=black!90,jTableBG] (hardwareRam) {};
  \foreach \i [evaluate= \i as \x using 0.05*\i] in {1,...,9} {
    \draw (0, 0) ++(\x, -0.125) rectangle +(0.05, 0.25);
  }

  \fill  (0.2,-0.125) rectangle +(0.05, 0.25);
  \coordinate (takenInterrupt) at (0.225, 0.125);

  \coordinate (execSyscall) at ($(p.north west)!0.25!(p.north east)$);

  \draw (execSyscall) edge [bend right=60,-Stealth,, "{\tiny
    \texttt{syscall}}" ',at start] (takenInterrupt);


  \draw  (5.75, 0) node[fill=black!70!green,jTableBG] (os) {};
\end{tikzpicture}

\pause
\lstinline|syscall| generates an interrupt. Control passes through the
ISV.

\begin{tikzpicture}
  \draw (0,0) node[RAMBox] (RAM) {};
  \draw node[below=0.0cm of RAM] (title) {RAM};

  \draw (2.7,0) node[pBox, minimum width=1.25cm] (p) {};

  \draw  (0,0) node[fill=black!90,jTableBG] (hardwareRam) {};
  \foreach \i [evaluate= \i as \x using 0.05*\i] in {1,...,9} {
    \draw (0, 0) ++(\x, -0.125) rectangle +(0.05, 0.25);
  }

  \fill  (0.2,-0.125) rectangle +(0.05, 0.25);
  \coordinate (takenInterrupt) at (0.225, 0.125);

  \coordinate (execSyscall) at ($(p.north west)!0.25!(p.north east)$);

  \draw (execSyscall) edge [bend right=60,-Stealth,, "{\tiny
    \texttt{syscall}}" ',at start] (takenInterrupt);


  \draw  (5.75, 0) node[fill=black!70!green,jTableBG] (os) {};
  \draw  (os.north) node[anchor=north east,fill=black!50!green,draw,fill,minimum
  width=0.625cm, minimum height=0.5cm] (handler) {};
  \foreach \i [evaluate= \i as \x using 0.05*\i] in {1,...,5} {
    \draw (handler.west) ++(\x, -0.125) rectangle +(0.05, 0.25);
  }

  \draw (takenInterrupt) edge [bend left, -Stealth,"{\tiny
    interrupt}",near end] (handler.north west);
\end{tikzpicture}

\pause
To the \lstinline|syscall| handler with its own jump table.

\begin{tikzpicture}
  \draw (0,0) node[RAMBox] (RAM) {};
  \draw node[below=0.0cm of RAM] (title) {RAM};

  \draw (2.7,0) node[pBox, minimum width=1.25cm] (p) {};

  \draw  (0,0) node[fill=black!90,jTableBG] (hardwareRam) {};
  \foreach \i [evaluate= \i as \x using 0.05*\i] in {1,...,9} {
    \draw (0, 0) ++(\x, -0.125) rectangle +(0.05, 0.25);
  }

  \fill  (0.2,-0.125) rectangle +(0.05, 0.25);
  \coordinate (takenInterrupt) at (0.225, 0.125);

  \coordinate (execSyscall) at ($(p.north west)!0.25!(p.north east)$);

  \draw (execSyscall) edge [bend right=60,-Stealth,, "{\tiny
    \texttt{syscall}}" ',at start] (takenInterrupt);


  \draw  (5.75, 0) node[fill=black!70!green,jTableBG] (os) {};
  \draw  (os.north) node[anchor=north east,fill=black!50!green,draw,fill,minimum
  width=0.625cm, minimum height=0.5cm] (handler) {};
  \foreach \i [evaluate= \i as \x using 0.05*\i] in {1,...,5} {
    \draw (handler.west) ++(\x, -0.125) rectangle +(0.05, 0.25);
  }

  \draw (takenInterrupt) edge [bend left, -Stealth,"{\tiny
    interrupt}",near end] (handler.north west);

  \fill (handler.west) ++(0.1, -0.125) rectangle +(0.05, 0.25);
\end{tikzpicture}

\end{frame}

\section{Devices}
\end{document}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: t
%%% End:
