Tidying up techical notes
[barrelfish] / doc / 017-arm / ARM.tex
1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 % Copyright (c) 2013, ETH Zurich.
3 % All rights reserved.
4 %
5 % This file is distributed under the terms in the attached LICENSE file.
6 % If you do not find this file, copies can be found by writing to:
7 % ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
8 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9
10 \documentclass[a4paper,twoside]{report} % for a report (default)
11
12 \usepackage{bftn} % You need this
13 \usepackage{multirow}
14 \usepackage{listings}
15 \usepackage{color}
16
17 \title{Barrelfish on ARMv7}   % title of report
18 \author{Simon Gerber \and Stefan Kaestle \and Timothy Roscoe \and
19   Pravin Shinde \and Gerd Zellweger}
20 \tnnumber{017}  % give the number of the tech report
21 \tnkey{ARMv7} % Short title, will appear in footer
22
23 % \date{Month Year} % Not needed - will be taken from version history
24
25 \newcommand{\todo}[1]{\note{\textbf{TODO:} #1}}
26
27 \begin{document}
28 \maketitle
29
30 \newcommand{\code}[1]{{\lstinline!#1!}}
31 \newcommand{\file}[1]{{\lstinline!#1!}}
32
33 %configure listings properly
34 \lstset{%
35   basicstyle=\small\ttfamily,
36   escapechar=@
37 }
38
39 \newcommand{\shell}{\$}
40 \newcommand{\home}{\$HOME}
41
42 \newcommand{\stefan}[1]{%
43   {\color{red}[{\color{red}{SK}} #1]}}
44
45 \newcommand{\gerd}[1]{%
46   {\color{red}[{\color{red}{GZ}} #1]}}
47
48 \newcommand{\simon}[1]{%
49   {\color{red}[{\color{red}{SG}} #1]}}
50
51 \newcommand{\pravin}[1]{%
52   {\color{red}[{\color{red}{PS}} #1]}}
53
54
55 %
56 % Include version history first
57 %
58 \begin{versionhistory}
59 \vhEntry{0.1}{05.12.2013}{SK}{Initial version}
60 \end{versionhistory}
61
62 % \intro{Abstract}              % Insert abstract here
63 % \intro{Acknowledgements}      % Uncomment (if needed) for acknowledgements
64 \tableofcontents                % Uncomment (if needed) for final draft
65 % \listoffigures                % Uncomment (if needed) for final draft
66 % \listoftables                 % Uncomment (if needed) for final draft
67
68 \lstset{
69   language=C,
70   basicstyle=\ttfamily \small,
71   flexiblecolumns=false,
72   basewidth={0.5em,0.45em},
73   boxpos=t,
74 }
75
76 \newcommand{\eclipse}{ECL\textsuperscript{i}PS\textsuperscript{e}\xspace}
77 \newcommand{\codesize}{\scriptsize}
78 \newcommand{\note}[1]{[\textcolor{red}{\emph{#1}}]}
79
80 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
81 \chapter{Introduction}
82
83 This document describes the state of support for ARM processors
84 in Barrelfish.
85
86 ARM hardware is highly diverse, and has evolved over time.  As a
87 research OS, Barrelfish focusses ARM support on a small number of
88 platforms based on wide availability, ease of maintenance, and
89 research interest.  
90
91 The principal processors with ARM support in Barrelfish at present are
92 as follows: 
93
94 \begin{itemize}
95 \item ARMv7a (Cortex A-series), in particular the Cortex A9. 
96 \item ARMv7m (Cortex M-series), in particular the Cortex M3. 
97 \item ARMv5 processors, in particular the Intel iXP2800 network
98   processor (which uses an XScale core). 
99 \end{itemize}
100
101 The main systems we target at present are:
102 \begin{itemize}
103 \item The Texas Instruments OMAP4460 SoC used in the PandaBoard ES
104   platform. 
105 \item The ARM VExpress\_EMM board, under emulation in the GEM5
106   simulator. 
107 \end{itemize}
108
109 In addition there is limited (and not tested) support in the
110 Barrelfish tree for:
111 \begin{itemize}
112 \item The Netronome i8000 card, incorporating a single Intel iXP2800
113   processor. 
114 \end{itemize}
115
116
117 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
118 \chapter{Implementations}\label{chap:impl}
119
120 \section{ARM in general}
121
122 \subsection{Compilation}
123 \label{sec:armcompile}
124
125 This section assumes a properly set up toolchain for Barrelfish as
126 described in \stefan{XXX}.
127
128 For cross-compiling Barrelfish for arm, we also require Mentor /
129 codesourcery toolchain (v 2012.03). You can check that the toolchain
130 is set up properly:
131
132 \begin{lstlisting}
133 @\shell@ arm-linux-gnueabi-gcc --version
134 arm-linux-gnueabi-gcc (Sourcery CodeBench Lite 2012.03-57) 4.6.3
135 Copyright (C) 2011 Free Software Foundation, Inc.
136 This is free software; see the source for copying conditions. There is NO
137 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
138 \end{lstlisting}
139
140 %--------------------------------------------------
141 \section{OMAP4460 specifics}
142
143 % Source: Claudio 3.1
144
145 The OMAP4460 is a system on a chip (SoC) by Texas Instruments,
146 intended for use in consumer devices like smartphones and tablet
147 computers. It contains:
148
149 \begin{itemize}
150 \item A dual core ARM Cortex-A9 processor
151 \item Two ARM Cortex-M3 processors
152 \item A hardware spinlock module
153 \item A mailbox module
154 \item Many devices to process media input and output
155 \end{itemize}
156
157 The intention is that the Cortex-A9 will be running a general purpose
158 operating system, while the Cortex-M3 processors will only be running
159 a real-time operating system to control the imaging subsystem.
160
161 The processor configuration in the OMAP4460 is somewhat
162 unconventional; for example, the Cortex-M3 processors share a
163 custom MMU with page faults handled by code running on the Cortex-A9
164 processors and hence are constrained to run in the same virtual
165 address at all times.  They are also not cache-coherent with the
166 Cortex-A9 cores. 
167
168 \subsection{Compilation}
169
170 To compile Barrelfish for the PandaBoard, first, make sure to
171 configure your toolchain as described in
172 Section~\ref{sec:armcompile}. Then execute:
173
174 \begin{lstlisting}
175 cd @\shell@SRC
176 mkdir build
177 cd build
178 ../hake/hake.sh -a armv7 -s ../
179 make pandaboard_image
180 \end{lstlisting}
181
182 \subsection{Boot process: first (bootstrap) core}
183
184 \todo{From AOS writeup?}
185
186 \subsection{Boot process: subsequent cores}
187
188 % source: AOS m6
189
190 Here is a brief overview of how the bootstrapping process for the second core
191 works: it waits for a signal from the BSP core (an interrupt), and when this
192 signal is received, the application core will read an address from a well-
193 defined register and start executing the code from this address.
194
195 To boot the second core, one can write the address of
196 a function to the register and send the inter-processor
197 interrupt. Following are some pointers to the documentation to help
198 understand the bootstrapping process in more detail:
199
200 \begin{itemize}
201 \item Section 27.4.4 in the OMAP44xx manual talks about the boot process for
202   application cores.
203 \item Pages 1144 \textit{ff.} in the OMAP44xx manual have the register
204   layout for the registers that are used in the boot process of the
205   second core. 
206 \end{itemize}
207
208 Note that the Barrelfish codebase distinguishes between the BSP (bootstrap)
209 processor and APP (application) processors. This distinction and naming
210 originates from Intel x86 support where the BIOS will choose a
211 distinguished BSP processor at start-up and the OS 
212 is responsible for starting the rest of the processors (the APP
213 processors). Although it works somewhat differently on 
214 ARM, the naming convention is applicable here as well.
215
216 Note that the second core will start working with the MMU disabled, so
217 is running in physical address space.  The bootstrapping code sets up a
218 stack, initial page tables and an initial Barrelfish dispatcher. 
219
220 \subsection{Physical address space}
221
222 Partitioned in half. Independent mem-server on every core, which work
223 independently.
224
225 \subsection{Interconnect driver}\label{sec:interconnect}
226
227 Communication between A9 cores on the OMAP processor is performed
228 using a variant of the CC-UMP interconnect driver, modified for the
229 32-byte cache line size of the ARMv7 architecture.  A notification
230 driver for inter-processor interrupts exists. 
231
232 The OMAP4460 also has mailbox hardware which can be used by both the
233 A9 and M3 cores.  Barrelfish support for this hardware is in
234 progress. 
235
236 \subsection{M3 cores}
237
238 Barrelfish also has rudimentary support for running on both the A9 and
239 M3 cores.  This is limited by the requirement that the M3 cores must
240 run in the same virtual address space, and do not have a way to
241 automatically change address space on a kernel trap.  For this reason,
242 we only execute on a single M3 core at present. 
243
244 \subsubsection{Booting M3 cores}
245
246 Before the Cortex-M3 can start executing code, the following steps
247 have to be taken by the Cortex-A9:
248
249 \begin{itemize}
250 \item Power on the Cortex-M3 subsystem
251 \item Activate the Cortex-M3 subsystem clock
252 \item Load the image to be executed into memory
253 \item Enable the L2 MMU
254 \item Set up mappings for the loaded image in the L2 MMU (can be
255   written directly into the TLB)
256 \item Write the first two entries of the vectortable (initial sp and
257   reset vector)
258 \item Take the Cortex-M3 out of reset
259 \end{itemize}
260
261 It is important to note that the Cortex-M3 is in a virtual address
262 space from the very beginning, reading the vector table at virtual
263 address 0. Inserting a 1:1 mapping for the kernel image greatly
264 simplifies the bootstrapping of memory management on the Cortex-M3
265 once it is running, because it needs to know the physical address of
266 the page tables it sets up.
267
268 %--------------------------------------------------
269 \section{gem5 specifics}
270
271 The Gem5~\cite{gem5:sigarch11} simulator combines the best aspects of
272 the M5~\cite{m5:micro06} and GEMS~\cite{gems:sigarch05}
273 simulators. With its flexible and highly modular design, Gem5 allows
274 the simulation of a wide range of systems. Gem5 supports a wide range
275 of ISAs like x86, SPARC, Alpha and, in our case most importantly,
276 ARM. In the following we will list some features of Gem5.
277
278 Gem5 supports four different CPU models: AtomicSimple, TimingSimple,
279 In-Order and O3. The first two are simple one-cycle-per-instruction
280 CPU models. The difference between the two lies in the way they handle
281 memory accesses. The AtomicSimple model completes all memory accesses
282 immediately, whereas the TimingSimple CPU models the timing of memory
283 accesses. Due to their simplicity, the simulation speed is far above
284 the other two models.  The InOrder CPU models an in-order pipeline and
285 focuses on timing and simulation accuracy. The pipeline can be
286 configured to model different numbers of stages and hardware threads.
287 The O3 CPU models a pipelined, out-of-order and possibly superscalar
288 CPU model. It simulates dependencies between instructions, memory
289 accesses, pipeline stages and functional units. With a load/store
290 queue and reorder buffer its possible to simulate superscalar
291 architectures as well as multiple hardware threads.
292
293 The Gem5 simulator provides a tight integration of Python into the
294 simulator. Python is mainly used for system configuration. Every
295 simulated building block of a system is implemented in C++ but are
296 also reflected as a Python class and derive from a single superclass
297 SimObject. This provides a very flexible way of system construction
298 and allows to tailor nearly every aspect of the system to our needs.
299 Python is also used to control the simulation, taking and restoring
300 snapshots as well as all the command line processing.
301
302 We use a VExpress\_EMM based system to run Barrelfish. The number of
303 cores can be passed as an argument to the gem5 script. Cores are
304 clocked at 1 GHz and main memory is 64 MB starting at 2 GB.
305
306 \subsection{Compilation}
307
308 In addition to the steps described in Section~\ref{sec:armcompile} you
309 will need a supported version of gem5.
310
311 \begin{lstlisting}
312 hg clone http://repo.gem5.org/gem5 -r 0fea324c832c gem5
313 scons build/ARM/gem5.fast
314 \end{lstlisting}
315 After the compilation of gem5 is finished, add the binary to your PATH.
316
317 Now, build Barrelfish like this:
318 \begin{lstlisting}
319 cd @\shell@SRC
320 mkdir build
321 cd build
322 ../hake/hake.sh -a armv7 -s ../
323 \end{lstlisting}
324
325 Be sure to set \code{armv7_platform} in
326 \file{<build_dir>/hake/Config.hs} to \texttt{gem5} in order to enable
327 the cache quirk workarounds for gem5 and proper offsets for the
328 platform simulated by gem5.
329
330 \begin{lstlisting}
331 make arm_gem5
332 \end{lstlisting}
333
334 To get the output of Barrelfish you can use \code{telnet localhost
335   3456}
336
337 NOTE 1: You can print the supported options of the gem5 script with
338 \code{gem5.fast ../tools/gem5/gem5script.py -h}
339
340 NOTE 2: If you use \code{--cpu-type=arm_detailed} (use \code{make
341 arm_gem5_detailed}), the simulation takes a long time (depending on
342 your machine up to an hour just to boot Barrelfish)
343
344 \subsection{Boot process: first (bootstrap) core}
345
346 % Source: Samuel's thesis, 4.1.1
347
348 This section gives a high-level overview of the boot up process of the
349 Barrelfish
350 kernel on ARMv7-a. In subsequent sections we will go more into details
351 involved
352 in the single steps.
353 \begin{itemize}
354 \item Setup kernel stack and ensure privileged mode
355 \item Allocate L1 page table for kernel
356 \item Create necessary mappings for address translation
357 \item Set translation table base register (TTBR) and domain
358   permissions
359 \item Activate MMU, relocate program counter and stack pointer
360 \item Invalidate TLB, setup arguments for first C-function arch init
361 \item Setup exception handling
362 \item Map the available physical memory in the kernel L1 page table
363 \item Parse command line and set corresponding variables
364 \item Initialize devices
365 \item Create a physical memory map for the available memory
366 \item Check ramdisk for errors
367 \item Initialize and switch to init’s address space
368 \item Load init image from ramdisk into memory
369 \item Load and create capabilities for modules defined by menu.lst
370 \item Start timer for scheduling
371 \item Schedule init and switch to user space
372 \item init brings up the monitor and mem serv
373 \item monitor spawns ramfsd, skb and all the other modules
374 \end{itemize}
375
376 \subsection{Boot process: subsequent cores}
377
378 % Source: Samuel, 4.2.2
379
380 The boot up protocol for the multi-core port differs in various ways
381 from the boot up procedure of our previous single-core port. We
382 therefore include this revised overview here. The first core is called
383 the bootstrap processor and every subsequent core is called an
384 application processor On bootstrap processor:
385
386 \begin{itemize}
387 \item Pass argument from bootloader to first C-function arch
388   init 18
389 \item Make multiboot information passed by bootloader globally
390   available
391 \item Create 1:1 mapping of address space and alias the same region at
392   high memory
393 \item Configure and activate MMU
394 \item Relocate kernel image to high memory
395 \item Reset mapping, only map in the physical memory aliased at high
396   memory
397 \item Parse command line and set corresponding variables
398 \item Initialize devices
399 \item Initialize and switch to init’s address space
400 \item Load init image into memory
401 \item Create capabilities for modules defined by the multiboot info
402 \item Schedule init and switch to user space
403 \item init brings up the monitor and mem serv
404 \item monitor spawns ramfsd, skb and all the other modules
405 \item spawnd parses its cmd line and tells the monitor to bring up a
406   new core
407 \item monitor setups inter-monitor communication channel
408 \item monitor allocates memory for new kernel and remote monitor
409 \item monitor loads kernel image and relocates it to destination
410   address
411 \item monitor setups boot information for new kernel
412 \item spawnd issues syscall to start new core
413 \item Kernel writes entry address for new core into SYSFLAG registers
414 \item Kernel raises software interrupt to start new core
415 \item Kernel spins on pseudo-lock until other kernel releases it
416 \item repeat steps 15 to 23 for each application processor
417 \end{itemize}
418
419 \subsection{Memory}
420
421 Like many other popular operating systems, Barrelfish employs a memory
422 split. The idea behind a memory split is to separate kernel code from
423 user space code in the virtual address space. This allows the kernel
424 to be mapped in every virtual address space of each user space
425 program, which is necessary to allow user space code to access kernel
426 features through the system call interface. If the kernel was not
427 mapped into the virtual address space of each program, it would be
428 impossible to jump to kernel code without switching the virtual
429 address space. Additionally ARMv7-a provides two translation table
430 base registers, TTBR0 and TTBR1. We can configure the system to use
431 TTBR0 for address translations of virtual addresses below 2GB and
432 TTBR1 for virtual address above 2GB. This saves us the explicit
433 mapping of the kernel pages into every L1 page table of each process.
434 Even though the kernel is mapped to each virtual address space, it is
435 invisible for the user space program. Accessing memory, which belongs
436 to the kernel, leads to a pagefault. Since many mappings can point to
437 the same physical memory, memory usage is not increased by this
438 technique.
439
440 \begin{figure}[htb]
441   \centering
442   \includegraphics[width=\linewidth]{figures/memory_layout.png}
443   \caption{Barrelfish memory layout for ARMv7 on gem5}
444   \label{fig:memory_layout}
445 \end{figure}
446
447 Figure~\ref{fig:memory_layout} shows the memory layout of the
448 single-core ARMv7-a port of Barrelfish. We have a memory split at 2GB,
449 where everything upwards is only accessible in privileged mode and the
450 lower 2GB of memory is accessible for user space programs. The
451 position of the kernel in the virtual space is hard- coded. The L1
452 page table of the kernel address space is located right after the
453 kernel and aligned to 16KB. We map the whole available physical memory
454 into the kernel’s virtual address space. The locations for the 64KB
455 kernel stack, the ramdisk aswell as the section for memory mapped
456 devices are hardcoded.  Overall the memory layout is very static and
457 turned out to be problematic with regard to multicore support, which
458 will be explained in section 4.2.
459
460
461 We still implement a memory split the same way we did in the
462 single-core port. The only real difference is that the kernel image
463 can now be loaded anywhere in memory instead of only at a fixed
464 location. The kernel stack and page tables are statically allocated
465 and part of the kernel image. Since the kernel is not statically
466 linked to a fixed address in high memory anymore, we have to relocate
467 the kernel image during boot up. We do this by adding our memory
468 offset constant (2GB) to the current kernel location to make sure the
469 kernel is in high memory after the relocation. The program counter and
470 stack pointer need to be relocated as well and we do this again by
471 just adding the memory offset constant to their current values. After
472 these relocations we can reset the 1:1 mapping of the physical memory
473 and only map in the high memory aliased regions to finally get our
474 desired memory layout. To simplify global shared data between kernels
475 at boot up, i.e. before the message passing has been set up, we
476 reserved the first MB of physical memory for this purpose.
477
478
479 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
480 \bibliographystyle{abbrv}
481 \bibliography{defs,barrelfish}
482
483 \end{document}
484
485 \end{document}