630f1e270a9f2d3912a3d0e53953f0b4b451d37f
[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 the ARM port of
84 Barrelfish~\cite{barrelfish:sosp09}.
85
86 \todo{Explain architectures and platforms}
87
88 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
89 \chapter{Barrelfish implementation on ARM}\label{chap:impl}
90
91 \todo{Explain that we have several: ARMv5, OMAP4460 A9, OMAP4460 M3
92   and the VExpress\_EMM emulated by gem5}
93
94 \section{ARM in general}
95
96 \subsection{Compilation}
97 \label{sec:armcompile}
98
99 This section assumes a properly set up toolchain for Barrelfish as
100 described in \stefan{XXX}.
101
102 For cross-compiling Barrelfish for arm, we also require Mentor /
103 codesourcery toolchain (v 2012.03). You can check that the toolchain
104 is set up properly:
105
106 \begin{lstlisting}
107 @\shell@ arm-linux-gnueabi-gcc --version
108 arm-linux-gnueabi-gcc (Sourcery CodeBench Lite 2012.03-57) 4.6.3
109 Copyright (C) 2011 Free Software Foundation, Inc.
110 This is free software; see the source for copying conditions. There is NO
111 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
112 \end{lstlisting}
113
114 %--------------------------------------------------
115 \section{OMAP4460 specifics}
116
117 % Source: Claudio 3.1
118
119 The OMAP4460 is a system on a chip (SoC) by Texas Instruments,
120 intended for use in consumer devices like smartphones and tablet
121 computers. It contains:
122
123 \begin{itemize}
124 \item A dual core ARM Cortex-A9 processor
125 \item Two ARM Cortex-M3 processors
126 \item A hardware spinlock module
127 \item A mailbox module
128 \item Many devices to process media input and output
129 \end{itemize}
130
131 The intention is that the Cortex-A9 will be running a general purpose
132 operating system, while the Cortex-M3 processors will only be running
133 a real-time operating system to control the imaging subsystem.
134
135 \subsection{Compilation}
136
137 To compile Barrelfish for the PandaBoard, first, make sure to
138 configure your toolchain as described in
139 Section~\ref{sec:armcompile}. Then execute:
140
141 \begin{lstlisting}
142 cd @\shell@SRC
143 mkdir build
144 cd build
145 ../hake/hake.sh -a armv7 -s ../
146 make pandaboard_image
147 \end{lstlisting}
148
149 \subsection{Boot process: first (bootstrap) core}
150
151 \todo{From AOS writeup?}
152
153 \subsection{Boot process: subsequent cores}
154
155 % source: AOS m6
156
157 Here is a brief overview of how the bootstrapping process for the second core
158 works: it waits for a signal from the BSP core (an interrupt), and when this
159 signal is received, the application core will read an address from a well-
160 defined register and start executing the code from this address.
161
162 So, you can give some work to the other core by simply writing the address of
163 a function to the register and sending the signal. Following are few pointers
164 to the documentation to help you to understand the bootstrapping process
165 in more details.
166
167 \begin{itemize}
168 \item Section 27.4.4 in the OMAP44xx manual talks about the boot process for
169   application cores
170 \item Pages 1144f in the OMAP44xx manual have the register layout for the
171   registers that are used in the boot process of the second core.
172 \end{itemize}
173
174 Note that the Barrelfish codebase distinguishes between the BSP (bootstrap)
175 processor and APP (application) processors. This distinction and naming
176 originates from Intels x86 where the BIOS will choose a distinguished BSP processor
177 for you at start-up and the OS programmer is responsible to start the rest
178 of the processors (the APP processors). Altough it works a bit different on
179 ARM, the naming convention is applicable here as well.
180
181 Remember that second core will start working with the MMU disabled, so
182 it only understands physical addresses at this time.  As the second
183 core will be doing function calls of it's own, it will need it's own
184 stack and some assembly code to setup stack and CPU state. As we just
185 want to get the second core up, you may want to setup and execute a
186 function on the second core in a very early stage of boot-up before
187 things become complicated with MMU, caching and interrupts.
188
189 \stefan{Are we booting the second core from user-level in our tree?}
190
191 \subsection{Physical address space}
192
193 Partitioned in half. Independent mem-server on every core, which work
194 independently.
195
196 \subsection{Interconnect driver}\label{sec:interconnect}
197
198 Mention that there is a mailbox. I don't think we have a driver for it
199 in the tree, but Claudio might have one.
200
201 \subsection{M3 cores}
202
203 \subsubsection{Booting M3 cores}
204
205 Before the Cortex-M3 can start executing code, the following steps
206 have to be taken by the Cortex-A9:
207
208 \begin{itemize}
209 \item Power on the Cortex-M3 subsystem
210 \item Activate the Cortex-M3 subsystem clock
211 \item Load the image to be executed into memory
212 \item Enable the L2 MMU
213 \item Set up mappings for the loaded image in the L2 MMU (can be
214   written directly into the TLB)
215 \item Write the first two entries of the vectortable (initial sp and
216   reset vector)
217 \item Take the Cortex-M3 out of reset
218 \end{itemize}
219
220 It is important to note that the Cortex-M3 is in a virtual address
221 space from the very beginning, reading the vector table at virtual
222 address 0. Inserting a 1:1 mapping for the kernel image greatly
223 simplifies the bootstrapping of memory management on the Cortex-M3
224 once it is running, because it needs to know the physical address of
225 the page tables it sets up.
226
227 %--------------------------------------------------
228 \section{gem5 specifics}
229
230 The Gem5~\cite{gem5:sigarch11} simulator combines the best aspects of
231 the M5~\cite{m5:micro06} and GEMS~\cite{gems:sigarch05}
232 simulators. With its flexible and highly modular design, Gem5 allows
233 the simulation of a wide range of systems. Gem5 supports a wide range
234 of ISAs like x86, SPARC, Alpha and, in our case most importantly,
235 ARM. In the following we will list some features of Gem5.
236
237 Gem5 supports four different CPU models: AtomicSimple, TimingSimple,
238 In-Order and O3. The first two are simple one-cycle-per-instruction
239 CPU models. The difference between the two lies in the way they handle
240 memory accesses. The AtomicSimple model completes all memory accesses
241 immediately, whereas the TimingSimple CPU models the timing of memory
242 accesses. Due to their simplicity, the simulation speed is far above
243 the other two models.  The InOrder CPU models an in-order pipeline and
244 focuses on timing and simulation accuracy. The pipeline can be
245 configured to model different numbers of stages and hardware threads.
246 The O3 CPU models a pipelined, out-of-order and possibly superscalar
247 CPU model. It simulates dependencies between instructions, memory
248 accesses, pipeline stages and functional units. With a load/store
249 queue and reorder buffer its possible to simulate superscalar
250 architectures as well as multiple hardware threads.
251
252 The Gem5 simulator provides a tight integration of Python into the
253 simulator. Python is mainly used for system configuration. Every
254 simulated building block of a system is implemented in C++ but are
255 also reflected as a Python class and derive from a single superclass
256 SimObject. This provides a very flexible way of system construction
257 and allows to tailor nearly every aspect of the system to our needs.
258 Python is also used to control the simulation, taking and restoring
259 snapshots as well as all the command line processing.
260
261 We use a VExpress\_EMM based system to run Barrelfish. The number of
262 cores can be passed as an argument to the gem5 script. Cores are
263 clocked at 1 GHz and main memory is 64 MB starting at 2 GB.
264
265 \subsection{Compilation}
266
267 % Source: Get from Samuel's README file
268
269 In addition to the steps described in Section~\ref{sec:armcompile} you
270 will need a supported version of gem5.
271
272 \begin{lstlisting}
273 hg clone http://repo.gem5.org/gem5 -r 0fea324c832c gem5
274 scons build/ARM/gem5.fast
275 \end{lstlisting}
276 After the compilation of gem5 is finished, add the binary to your PATH.
277
278 Now, build Barrelfish like this:
279 \begin{lstlisting}
280 cd @\shell@SRC
281 mkdir build
282 cd build
283 ../hake/hake.sh -a armv7 -s ../
284 \end{lstlisting}
285
286 Be sure to set \code{armv7_platform} in
287 \file{<build_dir>/hake/Config.hs} to \texttt{gem5} in order to enable
288 the cache quirk workarounds for gem5 and proper offsets for the
289 platform simulated by gem5.
290
291 \begin{lstlisting}
292 make arm_gem5
293 \end{lstlisting}
294
295 To get the output of Barrelfish you can use \code{telnet localhost
296   3456}
297
298 NOTE 1: You can print the supported options of the gem5 script with
299 \code{gem5.fast ../tools/gem5/gem5script.py -h}
300
301 NOTE 2: If you use \code{--cpu-type=arm_detailed} (use \code{make
302 arm_gem5_detailed}), the simulation takes a long time (depending on
303 your machine up to an hour just to boot Barrelfish)
304
305
306 \subsection{Boot process: first (bootstrap) core}
307
308 % Source: Samuel's thesis, 4.1.1
309
310 This section gives a high-level overview of the boot up process of the
311 Barrelfish
312 kernel on ARMv7-a. In subsequent sections we will go more into details
313 involved
314 in the single steps.
315 \begin{itemize}
316 \item Setup kernel stack and ensure privileged mode
317 \item Allocate L1 page table for kernel
318 \item Create necessary mappings for address translation
319 \item Set translation table base register (TTBR) and domain
320   permissions
321 \item Activate MMU, relocate program counter and stack pointer
322 \item Invalidate TLB, setup arguments for first C-function arch init
323 \item Setup exception handling
324 \item Map the available physical memory in the kernel L1 page table
325 \item Parse command line and set corresponding variables
326 \item Initialize devices
327 \item Create a physical memory map for the available memory
328 \item Check ramdisk for errors
329 \item Initialize and switch to init’s address space
330 \item Load init image from ramdisk into memory
331 \item Load and create capabilities for modules defined by menu.lst
332 \item Start timer for scheduling
333 \item Schedule init and switch to user space
334 \item init brings up the monitor and mem serv
335 \item monitor spawns ramfsd, skb and all the other modules
336 \end{itemize}
337
338 \subsection{Boot process: subsequent cores}
339
340 % Source: Samuel, 4.2.2
341
342 The boot up protocol for the multi-core port differs in various ways
343 from the boot up procedure of our previous single-core port. We
344 therefore include this revised overview here. The first core is called
345 the bootstrap processor and every subsequent core is called an
346 application processor On bootstrap processor:
347
348 \begin{itemize}
349 \item Pass argument from bootloader to first C-function arch
350   init 18
351 \item Make multiboot information passed by bootloader globally
352   available
353 \item Create 1:1 mapping of address space and alias the same region at
354   high memory
355 \item Configure and activate MMU
356 \item Relocate kernel image to high memory
357 \item Reset mapping, only map in the physical memory aliased at high
358   memory
359 \item Parse command line and set corresponding variables
360 \item Initialize devices
361 \item Initialize and switch to init’s address space
362 \item Load init image into memory
363 \item Create capabilities for modules defined by the multiboot info
364 \item Schedule init and switch to user space
365 \item init brings up the monitor and mem serv
366 \item monitor spawns ramfsd, skb and all the other modules
367 \item spawnd parses its cmd line and tells the monitor to bring up a
368   new core
369 \item monitor setups inter-monitor communication channel
370 \item monitor allocates memory for new kernel and remote monitor
371 \item monitor loads kernel image and relocates it to destination
372   address
373 \item monitor setups boot information for new kernel
374 \item spawnd issues syscall to start new core
375 \item Kernel writes entry address for new core into SYSFLAG registers
376 \item Kernel raises software interrupt to start new core
377 \item Kernel spins on pseudo-lock until other kernel releases it
378 \item repeat steps 15 to 23 for each application processor
379 \end{itemize}
380
381 \subsection{Memory}
382
383 Like many other popular operating systems, Barrelfish employs a memory
384 split. The idea behind a memory split is to separate kernel code from
385 user space code in the virtual address space. This allows the kernel
386 to be mapped in every virtual address space of each user space
387 program, which is necessary to allow user space code to access kernel
388 features through the system call interface. If the kernel was not
389 mapped into the virtual address space of each program, it would be
390 impossible to jump to kernel code without switching the virtual
391 address space. Additionally ARMv7-a provides two translation table
392 base registers, TTBR0 and TTBR1. We can configure the system to use
393 TTBR0 for address translations of virtual addresses below 2GB and
394 TTBR1 for virtual address above 2GB. This saves us the explicit
395 mapping of the kernel pages into every L1 page table of each process.
396 Even though the kernel is mapped to each virtual address space, it is
397 invisible for the user space program. Accessing memory, which belongs
398 to the kernel, leads to a pagefault. Since many mappings can point to
399 the same physical memory, memory usage is not increased by this
400 technique.
401
402 \begin{figure}[htb]
403   \centering
404   \includegraphics[width=\linewidth]{figures/memory_layout.png}
405   \caption{Barrelfish memory layout for ARMv7 on gem5}
406   \label{fig:memory_layout}
407 \end{figure}
408
409 Figure~\ref{fig:memory_layout} shows the memory layout of the
410 single-core ARMv7-a port of Barrelfish. We have a memory split at 2GB,
411 where everything upwards is only accessible in privileged mode and the
412 lower 2GB of memory is accessible for user space programs. The
413 position of the kernel in the virtual space is hard- coded. The L1
414 page table of the kernel address space is located right after the
415 kernel and aligned to 16KB. We map the whole available physical memory
416 into the kernel’s virtual address space. The locations for the 64KB
417 kernel stack, the ramdisk aswell as the section for memory mapped
418 devices are hardcoded.  Overall the memory layout is very static and
419 turned out to be problematic with regard to multicore support, which
420 will be explained in section 4.2.
421
422
423 We still implement a memory split the same way we did in the
424 single-core port. The only real difference is that the kernel image
425 can now be loaded anywhere in memory instead of only at a fixed
426 location. The kernel stack and page tables are statically allocated
427 and part of the kernel image. Since the kernel is not statically
428 linked to a fixed address in high memory anymore, we have to relocate
429 the kernel image during boot up. We do this by adding our memory
430 offset constant (2GB) to the current kernel location to make sure the
431 kernel is in high memory after the relocation. The program counter and
432 stack pointer need to be relocated as well and we do this again by
433 just adding the memory offset constant to their current values. After
434 these relocations we can reset the 1:1 mapping of the physical memory
435 and only map in the high memory aliased regions to finally get our
436 desired memory layout. To simplify global shared data between kernels
437 at boot up, i.e. before the message passing has been set up, we
438 reserved the first MB of physical memory for this purpose.
439
440
441 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
442 \chapter{Reflections on ARM as a platform}\label{chap:refl}
443
444 \section{Debugging}~\label{debugging}
445
446 Experience with JTAG?
447
448 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
449 \bibliographystyle{abbrv}
450 \bibliography{defs,barrelfish}
451
452 \end{document}
453
454 \end{document}