1This document describes how to build and run an Android system image targeting
2the ARM Fixed Virtual Platform or QEMU.
3
4## New to Android?
5
6If you do not already have the ``repo`` tool, or a copy of the Android
7source tree, please follow the Android instructions for [downloading the
8source](https://source.android.com/setup/build/downloading).
9
10## Building the kernel
11
12It is not normally necessary to build the kernel manually. By
13default, the ``fvp`` target will use the GKI prebuilts for kernel
14version 5.10. If you need to modify the kernel, if you need to use
15a different kernel branch, or if you need graphics in FVP, please
16follow the instructions below.
17
18```
19mkdir android-kernel-mainline
20cd android-kernel-mainline
21repo init -u https://android.googlesource.com/kernel/manifest -b common-android-mainline
22```
23
24Now, update the kernel and setup for building:
25```
26export FVP_KERNEL_PATH=$(pwd)
27# Remove any old fvp-patches cherry-pick branch.
28cd common && git checkout aosp/android-mainline && \
29  git branch -D fvp-patches 2> /dev/null; cd ..
30repo sync -j$(nproc) -q
31# One cherrypick currently required due to a bug with BoundsSan+EHCI.
32repo start fvp-patches common
33repo download -c kernel/common 1634850
34```
35
36To support graphics on FVP, one additional cherry pick is required. This only
37applies to the ``fvp`` target, and not ``fvp_mini``, and it is also not required
38for QEMU.
39
40```
41repo download -c kernel/common 1768866
42```
43
44Then, build the kernel.
45
46```
47BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh -j$(nproc)
48BUILD_CONFIG=common-modules/virtual-device/build.config.virtual_device.aarch64 build/build.sh -j$(nproc)
49```
50
51## Building the firmware (ARM Trusted Firmware and U-Boot) (FVP only, not required on QEMU)
52
53First, install ``dtc``, the device tree compiler. On Debian, this is in the
54``device-tree-compiler`` package. Return to the top level directory (`cd ..`), and run:
55```
56mkdir platform
57cd platform
58export FVP_FIRMWARE_PATH=$(pwd)
59repo init -u https://git.linaro.org/landing-teams/working/arm/manifest.git -m pinned-uboot.xml -b 20.01
60repo sync
61
62# The included copy of U-Boot is incompatible with this version of AOSP, switch to a recent upstream checkout.
63cd u-boot
64git fetch https://gitlab.denx.de/u-boot/u-boot.git/ master
65git checkout 18b9c98024ec89e00a57707f07ff6ada06089d26
66cd ..
67
68mkdir -p tools/gcc
69cd tools/gcc
70wget https://releases.linaro.org/components/toolchain/binaries/6.2-2016.11/aarch64-linux-gnu/gcc-linaro-6.2.1-2016.11-x86_64_aarch64-linux-gnu.tar.xz
71tar -xJf gcc-linaro-6.2.1-2016.11-x86_64_aarch64-linux-gnu.tar.xz
72cd ../..
73
74build-scripts/build-test-uboot.sh -p fvp all
75```
76
77## Building userspace
78
79Follow the Android instructions to [download the
80source](https://source.android.com/setup/build/downloading), and run the
81following in the source directory.
82
83```
84. build/envsetup.sh
85lunch fvp-eng # or fvp-userdebug, fvp_mini-eng, fvp_mini-userdebug
86```
87
88The fvp-* lunch targets will build a full Android with UI support, while
89`fvp_mini-*` will build a small subset needed to boot to shell and support
90command line executables.
91
92If you are using FVP, prepopulate the build directory with the
93firmware binaries. Normally, these are copied from the source tree
94as part of the build process, but not for this target yet. This step
95is not required when using QEMU.
96
97```
98mkdir -p $ANDROID_PRODUCT_OUT
99cp $FVP_FIRMWARE_PATH/output/fvp/fvp-uboot/uboot/{bl1,fip}.bin $ANDROID_PRODUCT_OUT/
100```
101
102If you built a custom kernel, copy or symlink the newly built kernel into your
103source tree. For example:
104```
105mkdir -p kernel/prebuilts/mykernel/arm64
106ln -s $FVP_KERNEL_PATH/out/android-mainline/dist/Image kernel/prebuilts/mykernel/arm64/kernel-mykernel
107
108mkdir -p kernel/prebuilts/common-modules/virtual-device/mykernel
109ln -s $FVP_KERNEL_PATH/out/android-mainline/dist kernel/prebuilts/common-modules/virtual-device/mykernel/arm64
110```
111Then set the ``TARGET_KERNEL_USE`` environment variable to the name that you
112gave to your kernel. For example, ``export TARGET_KERNEL_USE=mykernel``.
113
114Set any additional build environment variables.
115* To enable MTE on all platform binaries (by default it is only enabled on a
116  small subset) add `export SANITIZE_TARGET=memtag_heap` for Async mode, or
117  `export SANITIZE_TARGET=memtag_heap SANITIZE_TARGET_DIAG=memtag_heap` for Sync
118  mode.
119* To disable 32 bit support in fvp_mini-* targets use
120  `export FVP_MULTILIB_BUILD=false`.
121
122Finally, build the userspace image with `m`.
123
124## Running
125
126The same image can be used with either ARM Fixed Virtual Platform simulator, or
127with QEMU. Slowdown from QEMU is roughly 10-20x, where ARM's FVP is 100-200x.
128
129### Running the image in FVP
130
131The model may be obtained from [ARM's
132website](https://developer.arm.com/tools-and-software/simulation-models/fixed-virtual-platforms/arm-ecosystem-models)
133(under "Armv-A Base RevC AEM FVP").
134
135From a lunched environment, first set the value of the ``MODEL_BIN`` environment
136variable to the path to the model executable (it should end with something like
137`FVP_Base_RevC-2xAEMv8A/models/Linux64_GCC-6.4/FVP_Base_RevC-2xAEMv8A`). Then
138run the following command to launch the model:
139```
140device/generic/goldfish/fvpbase/run_model
141```
142Additional model parameters may be passed by appending them to the
143``run_model`` command. Add the following to enable MTE support in the model:
144```
145-C cluster0.has_arm_v8-5=1 \
146-C cluster0.memory_tagging_support_level=2 \
147-C bp.dram_metadata.is_enabled=1
148```
149
150To terminate the model, press ``Ctrl-] Ctrl-D`` to terminate the telnet
151connection.
152
153### Running the image in QEMU
154
155As an alternative to using FVP, the image may also be run in QEMU.
156QEMU is generally much faster than FVP, but its support for the
157latest ARM architectural features is relatively new compared to FVP,
158so it may have more bugs.
159
160As of the time of writing, no released version of QEMU can successfully
161boot the system to GUI due to bugs in its MTE support, so a development
162version with bug fixes must be used. The instructions below check out a
163commit that has been successfully tested.
164
165Check [QEMU wiki](https://wiki.qemu.org/Hosts/Linux#Building_QEMU_for_Linux) for
166the list of build dependencies. Common missing packages include `ninja-build`,
167`libpixman-1-dev`, and `libgtk-3-dev` for GUI support.
168
169```
170git clone https://github.com/qemu/qemu
171cd qemu
172git checkout 5c6295a45b4fceac913c11abc62488c49c02b9fd
173mkdir build
174cd build
175../configure --target-list=aarch64-softmmu
176ninja
177export QEMU_BIN=$(pwd)/qemu-system-aarch64
178```
179
180Then run the following command in a lunched environment to start the emulator:
181```
182device/generic/goldfish/fvpbase/run_qemu
183```
184Additional QEMU arguments may be passed by appending them to the ``run_qemu``
185command. One useful argument is ``-nographic``, which disables the GUI, which
186may be useful when working with ``fvp_mini`` or if the GUI is not needed.
187
188To terminate the emulator, press ``Ctrl-A c q <Enter>`` or close the GUI
189window.
190
191### Accessing the model via adb
192
193To connect to the model on the host:
194```
195adb connect localhost:5555
196```
197