docs: Added documentation from various places
authorStefan Kaestle <stefan.kaestle@inf.ethz.ch>
Mon, 9 Dec 2013 16:46:12 +0000 (17:46 +0100)
committerKornilios Kourtis <kkourt@inf.ethz.ch>
Wed, 11 Dec 2013 13:49:24 +0000 (14:49 +0100)
doc/017-arm/ARM.tex

index eb25701..9fb4939 100644 (file)
 \begin{document}
 \maketitle
 
+\newcommand{\code}[1]{{\lstinline!#1!}}
+\newcommand{\file}[1]{{\lstinline!#1!}}
+
+%configure listings properly
+\lstset{%
+  basicstyle=\small\ttfamily,
+  escapechar=@
+}
+
+\newcommand{\shell}{\$}
+\newcommand{\home}{\$HOME}
+
+\newcommand{\stefan}[1]{%
+  {\color{red}[{\color{red}{SK}} #1]}}
+
+\newcommand{\gerd}[1]{%
+  {\color{red}[{\color{red}{GZ}} #1]}}
+
+\newcommand{\simon}[1]{%
+  {\color{red}[{\color{red}{SG}} #1]}}
+
+\newcommand{\pravin}[1]{%
+  {\color{red}[{\color{red}{PS}} #1]}}
+
+
 %
 % Include version history first
 %
@@ -36,7 +61,7 @@
 
 % \intro{Abstract}             % Insert abstract here
 % \intro{Acknowledgements}     % Uncomment (if needed) for acknowledgements
-% \tableofcontents             % Uncomment (if needed) for final draft
+\tableofcontents               % Uncomment (if needed) for final draft
 % \listoffigures               % Uncomment (if needed) for final draft
 % \listoftables                        % Uncomment (if needed) for final draft
 
@@ -66,62 +91,311 @@ Barrelfish~\cite{barrelfish:sosp09}.
 \todo{Explain that we have several: ARMv5, OMAP4460 A9, OMAP4460 M3
   and the VExpress\_EMM emulated by gem5}
 
-\section{ARM specifics}
+\section{ARM in general}
+
+\subsection{Compilation}
+\label{sec:armcompile}
+
+This section assumes a properly set up toolchain for Barrelfish as
+described in \stefan{XXX}.
+
+For cross-compiling Barrelfish for arm, we also require Mentor /
+codesourcery toolchain (v 2012.03). You can check that the toolchain
+is set up properly:
+
+\begin{lstlisting}
+@\shell@ arm-linux-gnueabi-gcc --version
+arm-linux-gnueabi-gcc (Sourcery CodeBench Lite 2012.03-57) 4.6.3
+Copyright (C) 2011 Free Software Foundation, Inc.
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+\end{lstlisting}
 
 %--------------------------------------------------
 \section{OMAP4460 specifics}
 
-Dual core A9 with two M3 accelerators.
+% Source: Claudio 3.1
+
+The OMAP4460 is a system on a chip (SoC) by Texas Instruments,
+intended for use in consumer devices like smartphones and tablet
+computers. It contains:
+
+\begin{itemize}
+\item A dual core ARM Cortex-A9 processor
+\item Two ARM Cortex-M3 processors
+\item A hardware spinlock module
+\item A mailbox module
+\item Many devices to process media input and output
+\end{itemize}
+
+The intention is that the Cortex-A9 will be running a general purpose
+operating system, while the Cortex-M3 processors will only be running
+a real-time operating system to control the imaging subsystem.
 
 \subsection{Compilation}
 
-\todo{Get from public Barrelfish wiki}
+To compile Barrelfish for the PandaBoard, first, make sure to
+configure your toolchain as described in
+Section~\ref{sec:armcompile}. Then execute:
+
+\begin{lstlisting}
+cd @\shell@SRC
+mkdir build
+cd build
+../hake/hake.sh -a armv7 -s ../
+build pandaboard_image
+\end{lstlisting}
 
-\section{Boot process: first (bootstrap) core}
+\subsection{Boot process: first (bootstrap) core}
 
 \todo{From AOS writeup?}
 
-\section{Boot process: subsequent cores}
+\subsection{Boot process: subsequent cores}
+
+% source: AOS m6
+
+Here is a brief overview of how the bootstrapping process for the second core
+works: it waits for a signal from the BSP core (an interrupt), and when this
+signal is received, the application core will read an address from a well-
+defined register and start executing the code from this address.
 
-\todo{From AOS writeup?} 
+So, you can give some work to the other core by simply writing the address of
+a function to the register and sending the signal. Following are few pointers
+to the documentation to help you to understand the bootstrapping process
+in more details.
 
-\todo{Kornilios did a clean implementation, he should know}
+\begin{itemize}
+\item Section 27.4.4 in the OMAP44xx manual talks about the boot process for
+  application cores
+\item Pages 1144f in the OMAP44xx manual have the register layout for the
+  registers that are used in the boot process of the second core.
+\end{itemize}
 
-\section{Physical address space}
+Note that the Barrelfish codebase distinguishes between the BSP (bootstrap)
+processor and APP (application) processors. This distinction and naming
+originates from Intels x86 where the BIOS will choose a distinguished BSP processor
+for you at start-up and the OS programmer is responsible to start the rest
+of the processors (the APP processors). Altough it works a bit different on
+ARM, the naming convention is applicable here as well.
+
+Remember that second core will start working with the MMU disabled, so
+it only understands physical addresses at this time.  As the second
+core will be doing function calls of it's own, it will need it's own
+stack and some assembly code to setup stack and CPU state. As we just
+want to get the second core up, you may want to setup and execute a
+function on the second core in a very early stage of boot-up before
+things become complicated with MMU, caching and interrupts.
+
+\stefan{Are we booting the second core from user-level in our tree?}
+
+\subsection{Physical address space}
 
 Partitioned in half. Independent mem-server on every core, which work
 independently.
 
-\section{Interconnect driver}\label{sec:interconnect}
+\subsection{Interconnect driver}\label{sec:interconnect}
 
 Mention that there is a mailbox. I don't think we have a driver for it
 in the tree, but Claudio might have one.
 
-\section{M3 cores}
+\subsection{M3 cores}
 
-Get from Claudio's thesis.
+\subsubsection{Booting M3 cores}
 
-%--------------------------------------------------
-\section{gem5 specifics}
-
-\section{Compilation}
-
-\todo{Get from Samuel's README file}
-
-\section{Boot process: first (bootstrap) core}
+Before the Cortex-M3 can start executing code, the following steps
+have to be taken by the Cortex-A9:
 
-\todo{Get from Samuel's thesis, 4.1.1}
+\begin{itemize}
+\item Power on the Cortex-M3 subsystem
+\item Activate the Cortex-M3 subsystem clock
+\item Load the image to be executed into memory
+\item Enable the L2 MMU
+\item Set up mappings for the loaded image in the L2 MMU (can be
+  written directly into the TLB)
+\item Write the first two entries of the vectortable (initial sp and
+  reset vector)
+\item Take the Cortex-M3 out of reset
+\end{itemize}
 
-\section{Boot process: subsequent cores}
+It is important to note that the Cortex-M3 is in a virtual address
+space from the very beginning, reading the vector table at virtual
+address 0. Inserting a 1:1 mapping for the kernel image greatly
+simplifies the bootstrapping of memory management on the Cortex-M3
+once it is running, because it needs to know the physical address of
+the page tables it sets up.
 
-Write start address of second core in SYSFLAGS register and raise
-SWI.
+%--------------------------------------------------
+\section{gem5 specifics}
 
-\todo{Samuel, 4.2.2}
+\subsection{Compilation}
 
-\section{Memory}
+% Source: Get from Samuel's README file
+
+In addition to the steps described in Section~\ref{sec:armcompile} you
+will need a supported version of gem5.
+
+\begin{lstlisting}
+hg clone http://repo.gem5.org/gem5 -r 0fea324c832c gem5
+scons build/ARM/gem5.fast
+\end{lstlisting}
+After the compilation of gem5 is finished, add the binary to your PATH.
+
+Now, build Barrelfish like this:
+\begin{lstlisting}
+cd @\shell@SRC
+mkdir build
+cd build
+../hake/hake.sh -a armv7 -s ../
+\end{lstlisting}
+
+Be sure to set \code{armv7_platform} in
+\file{<build_dir>/hake/Config.hs} to \texttt{gem5} in order to enable
+the cache quirk workarounds for gem5 and proper offsets for the
+platform simulated by gem5.
+
+\begin{lstlisting}
+make arm_gem5
+\end{lstlisting}
+\item To get the output of Barrelfish you can use \code{telnet localhost
+  3456}
+\end{itemize}
+
+NOTE 1: You can print the supported options of the gem5 script with
+\code{gem5.fast ../tools/gem5/gem5script.py -h} 
+
+NOTE 2: If you use \code{--cpu-type=arm_detailed} (use \code{make
+arm_gem5_detailed}), the simulation takes a long time (depending on
+your machine up to an hour just to boot Barrelfish)
+
+
+\subsection{Boot process: first (bootstrap) core}
+
+% Source: Samuel's thesis, 4.1.1
+
+This section gives a high-level overview of the boot up process of the
+Barrelfish
+kernel on ARMv7-a. In subsequent sections we will go more into details
+involved
+in the single steps.
+\begin{itemize}
+\item Setup kernel stack and ensure privileged mode
+\item Allocate L1 page table for kernel
+\item Create necessary mappings for address translation
+\item Set translation table base register (TTBR) and domain
+  permissions
+\item Activate MMU, relocate program counter and stack pointer
+\item Invalidate TLB, setup arguments for first C-function arch init
+\item Setup exception handling
+\item Map the available physical memory in the kernel L1 page table
+\item Parse command line and set corresponding variables
+\item Initialize devices
+\item Create a physical memory map for the available memory
+\item Check ramdisk for errors
+\item Initialize and switch to init’s address space
+\item Load init image from ramdisk into memory
+\item Load and create capabilities for modules defined by menu.lst
+\item Start timer for scheduling
+\item Schedule init and switch to user space
+\item init brings up the monitor and mem serv
+\item monitor spawns ramfsd, skb and all the other modules
+\end{itemize}
+
+\subsection{Boot process: subsequent cores}
+
+% Source: Samuel, 4.2.2
+
+The boot up protocol for the multi-core port differs in various ways
+from the boot up procedure of our previous single-core port. We
+therefore include this revised overview here. The first core is called
+the bootstrap processor and every subsequent core is called an
+application processor On bootstrap processor:
+
+\begin{itemize}
+\item Pass argument from bootloader to first C-function arch
+  init 18
+\item Make multiboot information passed by bootloader globally
+  available
+\item Create 1:1 mapping of address space and alias the same region at
+  high memory
+\item Configure and activate MMU
+\item Relocate kernel image to high memory
+\item Reset mapping, only map in the physical memory aliased at high
+  memory
+\item Parse command line and set corresponding variables
+\item Initialize devices
+\item Initialize and switch to init’s address space
+\item Load init image into memory
+\item Create capabilities for modules defined by the multiboot info
+\item Schedule init and switch to user space
+\item init brings up the monitor and mem serv
+\item monitor spawns ramfsd, skb and all the other modules
+\item spawnd parses its cmd line and tells the monitor to bring up a
+  new core
+\item monitor setups inter-monitor communication channel
+\item monitor allocates memory for new kernel and remote monitor
+\item monitor loads kernel image and relocates it to destination
+  address
+\item monitor setups boot information for new kernel
+\item spawnd issues syscall to start new core
+\item Kernel writes entry address for new core into SYSFLAG registers
+\item Kernel raises software interrupt to start new core
+\item Kernel spins on pseudo-lock until other kernel releases it
+\item repeat steps 15 to 23 for each application processor
+\end{itemize}
+
+\subsection{Memory}
+
+Like many other popular operating systems, Barrelfish employs a memory
+split. The idea behind a memory split is to separate kernel code from
+user space code in the virtual address space. This allows the kernel
+to be mapped in every virtual address space of each user space
+program, which is necessary to allow user space code to access kernel
+features through the system call interface. If the kernel was not
+mapped into the virtual address space of each program, it would be
+impossible to jump to kernel code without switching the virtual
+address space. Additionally ARMv7-a provides two translation table
+base registers, TTBR0 and TTBR1. We can configure the system to use
+TTBR0 for address translations of virtual addresses below 2GB and
+TTBR1 for virtual address above 2GB. This saves us the explicit
+mapping of the kernel pages into every L1 page table of each process.
+Even though the kernel is mapped to each virtual address space, it is
+invisible for the user space program. Accessing memory, which belongs
+to the kernel, leads to a pagefault. Since many mappings can point to
+the same physical memory, memory usage is not increased by this
+technique. 
+
+%\includegraphics[width=\linewidth]{figures/memory_layout}
+
+Figure 1 shows the memory layout of the single-core ARMv7-a port of
+Barrelfish. We have a memory split at 2GB, where everything upwards is
+only accessible in privileged mode and the lower 2GB of memory is
+accessible for user space programs. The position of the kernel in the
+virtual space is hard- coded. The L1 page table of the kernel address
+space is located right after the kernel and aligned to 16KB. We map
+the whole available physical memory into the kernel’s virtual address
+space. The locations for the 64KB kernel stack, the ramdisk aswell as
+the section for memory mapped devices are hardcoded.  Overall the
+memory layout is very static and turned out to be problematic with
+regard to multicore support, which will be explained in section 4.2.
+
+
+We still implement a memory split the same way we did in the
+single-core port. The only real difference is that the kernel image
+can now be loaded anywhere in memory instead of only at a fixed
+location. The kernel stack and page tables are statically allocated
+and part of the kernel image. Since the kernel is not statically
+linked to a fixed address in high memory anymore, we have to relocate
+the kernel image during boot up. We do this by adding our memory
+offset constant (2GB) to the current kernel location to make sure the
+kernel is in high memory after the relocation. The program counter and
+stack pointer need to be relocated as well and we do this again by
+just adding the memory offset constant to their current values. After
+these relocations we can reset the 1:1 mapping of the physical memory
+and only map in the high memory aliased regions to finally get our
+desired memory layout. To simplify global shared data between kernels
+at boot up, i.e. before the message passing has been set up, we
+reserved the first MB of physical memory for this purpose.
 
-\todo{From Samuel's thesis, 4.1.2}
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \chapter{Reflections on ARM as a platform}\label{chap:refl}