xref: /arm-trusted-firmware/docs/plat/rpi3.rst (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700SchasingluluRaspberry Pi 3
2*91f16700Schasinglulu==============
3*91f16700Schasinglulu
4*91f16700SchasingluluThe `Raspberry Pi 3`_ is an inexpensive single-board computer that contains four
5*91f16700SchasingluluArm Cortex-A53 cores.
6*91f16700Schasinglulu
7*91f16700SchasingluluThe following instructions explain how to use this port of the TF-A with the
8*91f16700Schasingluludefault distribution of `Raspbian`_ because that's the distribution officially
9*91f16700Schasinglulusupported by the Raspberry Pi Foundation. At the moment of writing this, the
10*91f16700Schasingluluofficially supported kernel is a AArch32 kernel. This doesn't mean that this
11*91f16700Schasingluluport of TF-A can't boot a AArch64 kernel. The `Linux tree fork`_ maintained by
12*91f16700Schasingluluthe Foundation can be compiled for AArch64 by following the steps in
13*91f16700Schasinglulu`AArch64 kernel build instructions`_.
14*91f16700Schasinglulu
15*91f16700Schasinglulu**IMPORTANT NOTE**: This port isn't secure. All of the memory used is DRAM,
16*91f16700Schasingluluwhich is available from both the Non-secure and Secure worlds. This port
17*91f16700Schasinglulushouldn't be considered more than a prototype to play with and implement
18*91f16700Schasingluluelements like PSCI to support the Linux kernel.
19*91f16700Schasinglulu
20*91f16700SchasingluluDesign
21*91f16700Schasinglulu------
22*91f16700Schasinglulu
23*91f16700SchasingluluThe SoC used by the Raspberry Pi 3 is the Broadcom BCM2837. It is a SoC with a
24*91f16700SchasingluluVideoCore IV that acts as primary processor (and loads everything from the SD
25*91f16700Schasinglulucard) and is located between all Arm cores and the DRAM. Check the `Raspberry Pi
26*91f16700Schasinglulu3 documentation`_ for more information.
27*91f16700Schasinglulu
28*91f16700SchasingluluThis explains why it is possible to change the execution state (AArch64/AArch32)
29*91f16700Schasingluludepending on a few files on the SD card. We only care about the cases in which
30*91f16700Schasingluluthe cores boot in AArch64 mode.
31*91f16700Schasinglulu
32*91f16700SchasingluluThe rules are simple:
33*91f16700Schasinglulu
34*91f16700Schasinglulu- If a file called ``kernel8.img`` is located on the ``boot`` partition of the
35*91f16700Schasinglulu  SD card, it will load it and execute in EL2 in AArch64. Basically, it executes
36*91f16700Schasinglulu  a `default AArch64 stub`_ at address **0x0** that jumps to the kernel.
37*91f16700Schasinglulu
38*91f16700Schasinglulu- If there is also a file called ``armstub8.bin``, it will load it at address
39*91f16700Schasinglulu  **0x0** (instead of the default stub) and execute it in EL3 in AArch64. All
40*91f16700Schasinglulu  the cores are powered on at the same time and start at address **0x0**.
41*91f16700Schasinglulu
42*91f16700SchasingluluThis means that we can use the default AArch32 kernel provided in the official
43*91f16700Schasinglulu`Raspbian`_ distribution by renaming it to ``kernel8.img``, while TF-A and
44*91f16700Schasingluluanything else we need is in ``armstub8.bin``. This way we can forget about the
45*91f16700Schasingluludefault bootstrap code. When using a AArch64 kernel, it is only needed to make
46*91f16700Schasinglulusure that the name on the SD card is ``kernel8.img``.
47*91f16700Schasinglulu
48*91f16700SchasingluluIdeally, we want to load the kernel and have all cores available, which means
49*91f16700Schasingluluthat we need to make the secondary cores work in the way the kernel expects, as
50*91f16700Schasingluluexplained in `Secondary cores`_. In practice, a small bootstrap is needed
51*91f16700Schasinglulubetween TF-A and the kernel.
52*91f16700Schasinglulu
53*91f16700SchasingluluTo get the most out of a AArch32 kernel, we want to boot it in Hypervisor mode
54*91f16700Schasingluluin AArch32. This means that BL33 can't be in EL2 in AArch64 mode. The
55*91f16700Schasingluluarchitecture specifies that AArch32 Hypervisor mode isn't present when AArch64
56*91f16700Schasingluluis used for EL2. When using a AArch64 kernel, it should simply start in EL2.
57*91f16700Schasinglulu
58*91f16700SchasingluluPlacement of images
59*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~
60*91f16700Schasinglulu
61*91f16700SchasingluluThe file ``armstub8.bin`` contains BL1 and the FIP. It is needed to add padding
62*91f16700Schasinglulubetween them so that the addresses they are loaded to match the ones specified
63*91f16700Schasingluluwhen compiling TF-A. This is done automatically by the build system.
64*91f16700Schasinglulu
65*91f16700SchasingluluThe device tree block is loaded by the VideoCore loader from an appropriate
66*91f16700Schasinglulufile, but we can specify the address it is loaded to in ``config.txt``.
67*91f16700Schasinglulu
68*91f16700SchasingluluThe file ``kernel8.img`` contains a kernel image that is loaded to the address
69*91f16700Schasingluluspecified in ``config.txt``. The `Linux kernel tree`_ has information about how
70*91f16700Schasinglulua AArch32 Linux kernel image is loaded in ``Documentation/arm/Booting``:
71*91f16700Schasinglulu
72*91f16700Schasinglulu::
73*91f16700Schasinglulu
74*91f16700Schasinglulu    The zImage may also be placed in system RAM and called there.  The
75*91f16700Schasinglulu    kernel should be placed in the first 128MiB of RAM.  It is recommended
76*91f16700Schasinglulu    that it is loaded above 32MiB in order to avoid the need to relocate
77*91f16700Schasinglulu    prior to decompression, which will make the boot process slightly
78*91f16700Schasinglulu    faster.
79*91f16700Schasinglulu
80*91f16700SchasingluluThere are no similar restrictions for AArch64 kernels, as specified in the file
81*91f16700Schasinglulu``Documentation/arm64/booting.txt``.
82*91f16700Schasinglulu
83*91f16700SchasingluluThis means that we need to avoid the first 128 MiB of RAM when placing the
84*91f16700SchasingluluTF-A images (and specially the first 32 MiB, as they are directly used to
85*91f16700Schasingluluplace the uncompressed AArch32 kernel image. This way, both AArch32 and
86*91f16700SchasingluluAArch64 kernels can be placed at the same address.
87*91f16700Schasinglulu
88*91f16700SchasingluluIn the end, the images look like the following diagram when placed in memory.
89*91f16700SchasingluluAll addresses are Physical Addresses from the point of view of the Arm cores.
90*91f16700SchasingluluAgain, note that this is all just part of the same DRAM that goes from
91*91f16700Schasinglulu**0x00000000** to **0x3F000000**, it just has different names to simulate a real
92*91f16700Schasinglulusecure platform!
93*91f16700Schasinglulu
94*91f16700Schasinglulu::
95*91f16700Schasinglulu
96*91f16700Schasinglulu    0x00000000 +-----------------+
97*91f16700Schasinglulu               |       ROM       | BL1
98*91f16700Schasinglulu    0x00020000 +-----------------+
99*91f16700Schasinglulu               |       FIP       |
100*91f16700Schasinglulu    0x00200000 +-----------------+
101*91f16700Schasinglulu               |                 |
102*91f16700Schasinglulu               |       ...       |
103*91f16700Schasinglulu               |                 |
104*91f16700Schasinglulu    0x01000000 +-----------------+
105*91f16700Schasinglulu               |       DTB       | (Loaded by the VideoCore)
106*91f16700Schasinglulu               +-----------------+
107*91f16700Schasinglulu               |                 |
108*91f16700Schasinglulu               |       ...       |
109*91f16700Schasinglulu               |                 |
110*91f16700Schasinglulu    0x02000000 +-----------------+
111*91f16700Schasinglulu               |     Kernel      | (Loaded by the VideoCore)
112*91f16700Schasinglulu               +-----------------+
113*91f16700Schasinglulu               |                 |
114*91f16700Schasinglulu               |       ...       |
115*91f16700Schasinglulu               |                 |
116*91f16700Schasinglulu    0x10000000 +-----------------+
117*91f16700Schasinglulu               |   Secure SRAM   | BL2, BL31
118*91f16700Schasinglulu    0x10100000 +-----------------+
119*91f16700Schasinglulu               |   Secure DRAM   | BL32 (Secure payload)
120*91f16700Schasinglulu    0x11000000 +-----------------+
121*91f16700Schasinglulu               | Non-secure DRAM | BL33
122*91f16700Schasinglulu               +-----------------+
123*91f16700Schasinglulu               |                 |
124*91f16700Schasinglulu               |       ...       |
125*91f16700Schasinglulu               |                 |
126*91f16700Schasinglulu    0x3F000000 +-----------------+
127*91f16700Schasinglulu               |       I/O       |
128*91f16700Schasinglulu    0x40000000 +-----------------+
129*91f16700Schasinglulu
130*91f16700SchasingluluThe area between **0x10000000** and **0x11000000** has to be manually protected
131*91f16700Schasingluluso that the kernel doesn't use it. The current port tries to modify the live DTB
132*91f16700Schasingluluto add a memreserve region that reserves the previously mentioned area.
133*91f16700Schasinglulu
134*91f16700SchasingluluIf this is not possible, the user may manually add ``memmap=16M$256M`` to the
135*91f16700Schasinglulucommand line passed to the kernel in ``cmdline.txt``. See the `Setup SD card`_
136*91f16700Schasingluluinstructions to see how to do it. This system is strongly discouraged.
137*91f16700Schasinglulu
138*91f16700SchasingluluThe last 16 MiB of DRAM can only be accessed by the VideoCore, that has
139*91f16700Schasingluludifferent mappings than the Arm cores in which the I/O addresses don't overlap
140*91f16700Schasingluluthe DRAM. The memory reserved to be used by the VideoCore is always placed at
141*91f16700Schasingluluthe end of the DRAM, so this space isn't wasted.
142*91f16700Schasinglulu
143*91f16700SchasingluluConsidering the 128 MiB allocated to the GPU and the 16 MiB allocated for
144*91f16700SchasingluluTF-A, there are 880 MiB available for Linux.
145*91f16700Schasinglulu
146*91f16700SchasingluluBoot sequence
147*91f16700Schasinglulu~~~~~~~~~~~~~
148*91f16700Schasinglulu
149*91f16700SchasingluluThe boot sequence of TF-A is the usual one except when booting an AArch32
150*91f16700Schasinglulukernel. In that case, BL33 is booted in AArch32 Hypervisor mode so that it
151*91f16700Schasinglulucan jump to the kernel in the same mode and let it take over that privilege
152*91f16700Schasinglululevel. If BL33 was running in EL2 in AArch64 (as in the default bootflow of
153*91f16700SchasingluluTF-A) it could only jump to the kernel in AArch32 in Supervisor mode.
154*91f16700Schasinglulu
155*91f16700SchasingluluThe `Linux kernel tree`_ has instructions on how to jump to the Linux kernel
156*91f16700Schasingluluin ``Documentation/arm/Booting`` and ``Documentation/arm64/booting.txt``. The
157*91f16700Schasinglulubootstrap should take care of this.
158*91f16700Schasinglulu
159*91f16700SchasingluluThis port support a direct boot of the Linux kernel from the firmware (as a BL33
160*91f16700Schasingluluimage). Alternatively, U-Boot or other bootloaders may be used.
161*91f16700Schasinglulu
162*91f16700SchasingluluSecondary cores
163*91f16700Schasinglulu~~~~~~~~~~~~~~~
164*91f16700Schasinglulu
165*91f16700SchasingluluThis port of the Trusted Firmware-A supports ``PSCI_CPU_ON``,
166*91f16700Schasinglulu``PSCI_SYSTEM_RESET`` and ``PSCI_SYSTEM_OFF``. The last one doesn't really turn
167*91f16700Schasingluluthe system off, it simply reboots it and asks the VideoCore firmware to keep it
168*91f16700Schasingluluin a low power mode permanently.
169*91f16700Schasinglulu
170*91f16700SchasingluluThe kernel used by `Raspbian`_ doesn't have support for PSCI, so it is needed to
171*91f16700Schasingluluuse mailboxes to trap the secondary cores until they are ready to jump to the
172*91f16700Schasinglulukernel. This mailbox is located at a different address in the AArch32 default
173*91f16700Schasinglulukernel than in the AArch64 kernel.
174*91f16700Schasinglulu
175*91f16700SchasingluluKernels with PSCI support can use the PSCI calls instead for a cleaner boot.
176*91f16700Schasinglulu
177*91f16700SchasingluluAlso, this port of TF-A has another Trusted Mailbox in Shared BL RAM. During
178*91f16700Schasinglulucold boot, all secondary cores wait in a loop until they are given given an
179*91f16700Schasingluluaddress to jump to in this Mailbox (``bl31_warm_entrypoint``).
180*91f16700Schasinglulu
181*91f16700SchasingluluOnce BL31 has finished and the primary core has jumped to the BL33 payload, it
182*91f16700Schasingluluhas to call ``PSCI_CPU_ON`` to release the secondary CPUs from the wait loop.
183*91f16700SchasingluluThe payload then makes them wait in another waitloop listening from messages
184*91f16700Schasinglulufrom the kernel. When the primary CPU jumps into the kernel, it will send an
185*91f16700Schasingluluaddress to the mailbox so that the secondary CPUs jump to it and are recognised
186*91f16700Schasingluluby the kernel.
187*91f16700Schasinglulu
188*91f16700SchasingluluBuild Instructions
189*91f16700Schasinglulu------------------
190*91f16700Schasinglulu
191*91f16700SchasingluluTo boot a AArch64 kernel, only the AArch64 toolchain is required.
192*91f16700Schasinglulu
193*91f16700SchasingluluTo boot a AArch32 kernel, both AArch64 and AArch32 toolchains are required. The
194*91f16700SchasingluluAArch32 toolchain is needed for the AArch32 bootstrap needed to load a 32-bit
195*91f16700Schasinglulukernel.
196*91f16700Schasinglulu
197*91f16700SchasingluluThe build system concatenates BL1 and the FIP so that the addresses match the
198*91f16700Schasingluluones in the memory map. The resulting file is ``armstub8.bin``, located in the
199*91f16700Schasinglulubuild folder (e.g. ``build/rpi3/debug/armstub8.bin``). To know how to use this
200*91f16700Schasinglulufile, follow the instructions in `Setup SD card`_.
201*91f16700Schasinglulu
202*91f16700SchasingluluThe following build options are supported:
203*91f16700Schasinglulu
204*91f16700Schasinglulu- ``RPI3_BL33_IN_AARCH32``: This port can load a AArch64 or AArch32 BL33 image.
205*91f16700Schasinglulu  By default this option is 0, which means that TF-A will jump to BL33 in EL2
206*91f16700Schasinglulu  in AArch64 mode. If set to 1, it will jump to BL33 in Hypervisor in AArch32
207*91f16700Schasinglulu  mode.
208*91f16700Schasinglulu
209*91f16700Schasinglulu- ``PRELOADED_BL33_BASE``: Used to specify the address of a BL33 binary that has
210*91f16700Schasinglulu  been preloaded by any other system than using the firmware. ``BL33`` isn't
211*91f16700Schasinglulu  needed in the build command line if this option is used. Specially useful
212*91f16700Schasinglulu  because the file ``kernel8.img`` can be loaded anywhere by modifying the file
213*91f16700Schasinglulu  ``config.txt``. It doesn't have to contain a kernel, it could have any
214*91f16700Schasinglulu  arbitrary payload.
215*91f16700Schasinglulu
216*91f16700Schasinglulu- ``RPI3_DIRECT_LINUX_BOOT``: Disabled by default. Set to 1 to enable the direct
217*91f16700Schasinglulu  boot of the Linux kernel from the firmware. Option ``RPI3_PRELOADED_DTB_BASE``
218*91f16700Schasinglulu  is mandatory when the direct Linux kernel boot is used. Options
219*91f16700Schasinglulu  ``PRELOADED_BL33_BASE`` will most likely be needed as well because it is
220*91f16700Schasinglulu  unlikely that the kernel image will fit in the space reserved for BL33 images.
221*91f16700Schasinglulu  This option can be combined with ``RPI3_BL33_IN_AARCH32`` in order to boot a
222*91f16700Schasinglulu  32-bit kernel. The only thing this option does is to set the arguments in
223*91f16700Schasinglulu  registers x0-x3 or r0-r2 as expected by the kernel.
224*91f16700Schasinglulu
225*91f16700Schasinglulu- ``RPI3_PRELOADED_DTB_BASE``: Auxiliary build option needed when using
226*91f16700Schasinglulu  ``RPI3_DIRECT_LINUX_BOOT=1``. This option allows to specify the location of a
227*91f16700Schasinglulu  DTB in memory.
228*91f16700Schasinglulu
229*91f16700Schasinglulu- ``RPI3_RUNTIME_UART``: Indicates whether the UART should be used at runtime
230*91f16700Schasinglulu  or disabled. ``-1`` (default) disables the runtime UART. Any other value
231*91f16700Schasinglulu  enables the default UART (currently UART1) for runtime messages.
232*91f16700Schasinglulu
233*91f16700Schasinglulu- ``RPI3_USE_UEFI_MAP``: Set to 1 to build ATF with the altername memory
234*91f16700Schasinglulu  mapping required for an UEFI firmware payload. These changes are needed
235*91f16700Schasinglulu  to be able to run Windows on ARM64. This option, which is disabled by
236*91f16700Schasinglulu  default, results in the following memory mappings:
237*91f16700Schasinglulu
238*91f16700Schasinglulu::
239*91f16700Schasinglulu
240*91f16700Schasinglulu    0x00000000 +-----------------+
241*91f16700Schasinglulu               |       ROM       | BL1
242*91f16700Schasinglulu    0x00010000 +-----------------+
243*91f16700Schasinglulu               |       DTB       | (Loaded by the VideoCore)
244*91f16700Schasinglulu    0x00020000 +-----------------+
245*91f16700Schasinglulu               |       FIP       |
246*91f16700Schasinglulu    0x00030000 +-----------------+
247*91f16700Schasinglulu               |                 |
248*91f16700Schasinglulu               |  UEFI PAYLOAD   |
249*91f16700Schasinglulu               |                 |
250*91f16700Schasinglulu    0x00200000 +-----------------+
251*91f16700Schasinglulu               |   Secure SRAM   | BL2, BL31
252*91f16700Schasinglulu    0x00300000 +-----------------+
253*91f16700Schasinglulu               |   Secure DRAM   | BL32 (Secure payload)
254*91f16700Schasinglulu    0x00400000 +-----------------+
255*91f16700Schasinglulu               |                 |
256*91f16700Schasinglulu               |                 |
257*91f16700Schasinglulu               | Non-secure DRAM | BL33
258*91f16700Schasinglulu               |                 |
259*91f16700Schasinglulu               |                 |
260*91f16700Schasinglulu    0x01000000 +-----------------+
261*91f16700Schasinglulu               |                 |
262*91f16700Schasinglulu               |       ...       |
263*91f16700Schasinglulu               |                 |
264*91f16700Schasinglulu    0x3F000000 +-----------------+
265*91f16700Schasinglulu               |       I/O       |
266*91f16700Schasinglulu
267*91f16700Schasinglulu- ``BL32``: This port can load and run OP-TEE. The OP-TEE image is optional.
268*91f16700Schasinglulu  Please use the code from `here <https://github.com/OP-TEE/optee_os>`__.
269*91f16700Schasinglulu  Build the Trusted Firmware with option ``BL32=tee-header_v2.bin
270*91f16700Schasinglulu  BL32_EXTRA1=tee-pager_v2.bin  BL32_EXTRA2=tee-pageable_v2.bin``
271*91f16700Schasinglulu  to put the binaries into the FIP.
272*91f16700Schasinglulu
273*91f16700Schasinglulu  .. warning::
274*91f16700Schasinglulu     If OP-TEE is used it may be needed to add the following options to the
275*91f16700Schasinglulu     Linux command line so that the USB driver doesn't use FIQs:
276*91f16700Schasinglulu     ``dwc_otg.fiq_enable=0 dwc_otg.fiq_fsm_enable=0 dwc_otg.nak_holdoff=0``.
277*91f16700Schasinglulu     This will unfortunately reduce the performance of the USB driver. It is
278*91f16700Schasinglulu     needed when using Raspbian, for example.
279*91f16700Schasinglulu
280*91f16700Schasinglulu- ``TRUSTED_BOARD_BOOT``: This port supports TBB. Set this option to 1 to enable
281*91f16700Schasinglulu  it. In order to use TBB, you might want to set ``GENERATE_COT=1`` to let the
282*91f16700Schasinglulu  contents of the FIP automatically signed by the build process. The ROT key
283*91f16700Schasinglulu  will be generated and output to ``rot_key.pem`` in the build directory. It is
284*91f16700Schasinglulu  able to set ROT_KEY to your own key in PEM format.  Also in order to build,
285*91f16700Schasinglulu  you need to clone mbed TLS from `here <https://github.com/ARMmbed/mbedtls>`__.
286*91f16700Schasinglulu  ``MBEDTLS_DIR`` must point at the mbed TLS source directory.
287*91f16700Schasinglulu
288*91f16700Schasinglulu- ``ENABLE_STACK_PROTECTOR``: Disabled by default. It uses the hardware RNG of
289*91f16700Schasinglulu  the board.
290*91f16700Schasinglulu
291*91f16700SchasingluluThe following is not currently supported:
292*91f16700Schasinglulu
293*91f16700Schasinglulu- AArch32 for TF-A itself.
294*91f16700Schasinglulu
295*91f16700Schasinglulu- ``EL3_PAYLOAD_BASE``: The reason is that you can already load anything to any
296*91f16700Schasinglulu  address by changing the file ``armstub8.bin``, so there's no point in using
297*91f16700Schasinglulu  TF-A in this case.
298*91f16700Schasinglulu
299*91f16700SchasingluluBuilding the firmware for kernels that don't support PSCI
300*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
301*91f16700Schasinglulu
302*91f16700SchasingluluThis is the case for the 32-bit image of Raspbian, for example. 64-bit kernels
303*91f16700Schasinglulualways support PSCI, but they may not know that the system understands PSCI due
304*91f16700Schasingluluto an incorrect DTB file.
305*91f16700Schasinglulu
306*91f16700SchasingluluFirst, clone and compile the 32-bit version of the `Raspberry Pi 3 TF-A
307*91f16700Schasinglulubootstrap`_. Choose the one needed for the architecture of your kernel.
308*91f16700Schasinglulu
309*91f16700SchasingluluThen compile TF-A. For a 32-bit kernel, use the following command line:
310*91f16700Schasinglulu
311*91f16700Schasinglulu.. code:: shell
312*91f16700Schasinglulu
313*91f16700Schasinglulu    CROSS_COMPILE=aarch64-linux-gnu- make PLAT=rpi3             \
314*91f16700Schasinglulu    RPI3_BL33_IN_AARCH32=1                                      \
315*91f16700Schasinglulu    BL33=../rpi3-arm-tf-bootstrap/aarch32/el2-bootstrap.bin
316*91f16700Schasinglulu
317*91f16700SchasingluluFor a 64-bit kernel, use this other command line:
318*91f16700Schasinglulu
319*91f16700Schasinglulu.. code:: shell
320*91f16700Schasinglulu
321*91f16700Schasinglulu    CROSS_COMPILE=aarch64-linux-gnu- make PLAT=rpi3             \
322*91f16700Schasinglulu    BL33=../rpi3-arm-tf-bootstrap/aarch64/el2-bootstrap.bin
323*91f16700Schasinglulu
324*91f16700SchasingluluHowever, enabling PSCI support in a 64-bit kernel is really easy. In the
325*91f16700Schasinglulurepository `Raspberry Pi 3 TF-A bootstrap`_ there is a patch that can be applied
326*91f16700Schasingluluto the Linux kernel tree maintained by the Raspberry Pi foundation. It modifes
327*91f16700Schasingluluthe DTS to tell the kernel to use PSCI. Once this patch is applied, follow the
328*91f16700Schasingluluinstructions in `AArch64 kernel build instructions`_ to get a working 64-bit
329*91f16700Schasinglulukernel image and supporting files.
330*91f16700Schasinglulu
331*91f16700SchasingluluBuilding the firmware for kernels that support PSCI
332*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
333*91f16700Schasinglulu
334*91f16700SchasingluluFor a 64-bit kernel:
335*91f16700Schasinglulu
336*91f16700Schasinglulu.. code:: shell
337*91f16700Schasinglulu
338*91f16700Schasinglulu    CROSS_COMPILE=aarch64-linux-gnu- make PLAT=rpi3             \
339*91f16700Schasinglulu    PRELOADED_BL33_BASE=0x02000000                              \
340*91f16700Schasinglulu    RPI3_PRELOADED_DTB_BASE=0x01000000                          \
341*91f16700Schasinglulu    RPI3_DIRECT_LINUX_BOOT=1
342*91f16700Schasinglulu
343*91f16700SchasingluluFor a 32-bit kernel:
344*91f16700Schasinglulu
345*91f16700Schasinglulu.. code:: shell
346*91f16700Schasinglulu
347*91f16700Schasinglulu    CROSS_COMPILE=aarch64-linux-gnu- make PLAT=rpi3             \
348*91f16700Schasinglulu    PRELOADED_BL33_BASE=0x02000000                              \
349*91f16700Schasinglulu    RPI3_PRELOADED_DTB_BASE=0x01000000                          \
350*91f16700Schasinglulu    RPI3_DIRECT_LINUX_BOOT=1                                    \
351*91f16700Schasinglulu    RPI3_BL33_IN_AARCH32=1
352*91f16700Schasinglulu
353*91f16700SchasingluluAArch64 kernel build instructions
354*91f16700Schasinglulu---------------------------------
355*91f16700Schasinglulu
356*91f16700SchasingluluThe following instructions show how to install and run a AArch64 kernel by
357*91f16700Schasingluluusing a SD card with the default `Raspbian`_ install as base. Skip them if you
358*91f16700Schasingluluwant to use the default 32-bit kernel.
359*91f16700Schasinglulu
360*91f16700SchasingluluNote that this system won't be fully 64-bit because all the tools in the
361*91f16700Schasinglulufilesystem are 32-bit binaries, but it's a quick way to get it working, and it
362*91f16700Schasingluluallows the user to run 64-bit binaries in addition to 32-bit binaries.
363*91f16700Schasinglulu
364*91f16700Schasinglulu1. Clone the `Linux tree fork`_ maintained by the Raspberry Pi Foundation. To
365*91f16700Schasinglulu   speed things up, do a shallow clone of the desired branch.
366*91f16700Schasinglulu
367*91f16700Schasinglulu.. code:: shell
368*91f16700Schasinglulu
369*91f16700Schasinglulu    git clone --depth=1 -b rpi-4.18.y https://github.com/raspberrypi/linux
370*91f16700Schasinglulu    cd linux
371*91f16700Schasinglulu
372*91f16700Schasinglulu2. Configure and compile the kernel. Adapt the number after ``-j`` so that it is
373*91f16700Schasinglulu   1.5 times the number of CPUs in your computer. This may take some time to
374*91f16700Schasinglulu   finish.
375*91f16700Schasinglulu
376*91f16700Schasinglulu.. code:: shell
377*91f16700Schasinglulu
378*91f16700Schasinglulu    make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcmrpi3_defconfig
379*91f16700Schasinglulu    make -j 6 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
380*91f16700Schasinglulu
381*91f16700Schasinglulu3. Copy the kernel image and the device tree to the SD card. Replace the path
382*91f16700Schasinglulu   by the corresponding path in your computers to the ``boot`` partition of the
383*91f16700Schasinglulu   SD card.
384*91f16700Schasinglulu
385*91f16700Schasinglulu.. code:: shell
386*91f16700Schasinglulu
387*91f16700Schasinglulu    cp arch/arm64/boot/Image /path/to/boot/kernel8.img
388*91f16700Schasinglulu    cp arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b.dtb /path/to/boot/
389*91f16700Schasinglulu    cp arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b-plus.dtb /path/to/boot/
390*91f16700Schasinglulu
391*91f16700Schasinglulu4. Install the kernel modules. Replace the path by the corresponding path to the
392*91f16700Schasinglulu   filesystem partition of the SD card on your computer.
393*91f16700Schasinglulu
394*91f16700Schasinglulu.. code:: shell
395*91f16700Schasinglulu
396*91f16700Schasinglulu    make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- \
397*91f16700Schasinglulu    INSTALL_MOD_PATH=/path/to/filesystem modules_install
398*91f16700Schasinglulu
399*91f16700Schasinglulu5. Follow the instructions in `Setup SD card`_ except for the step of renaming
400*91f16700Schasinglulu   the existing ``kernel7.img`` (we have already copied a AArch64 kernel).
401*91f16700Schasinglulu
402*91f16700SchasingluluSetup SD card
403*91f16700Schasinglulu-------------
404*91f16700Schasinglulu
405*91f16700SchasingluluThe instructions assume that you have an SD card with a fresh install of
406*91f16700Schasinglulu`Raspbian`_ (or that, at least, the ``boot`` partition is untouched, or nearly
407*91f16700Schasingluluuntouched). They have been tested with the image available in 2018-03-13.
408*91f16700Schasinglulu
409*91f16700Schasinglulu1. Insert the SD card and open the ``boot`` partition.
410*91f16700Schasinglulu
411*91f16700Schasinglulu2. Rename ``kernel7.img`` to ``kernel8.img``. This tricks the VideoCore
412*91f16700Schasinglulu   bootloader into booting the Arm cores in AArch64 mode, like TF-A needs,
413*91f16700Schasinglulu   even though the kernel is not compiled for AArch64.
414*91f16700Schasinglulu
415*91f16700Schasinglulu3. Copy ``armstub8.bin`` here. When ``kernel8.img`` is available, The VideoCore
416*91f16700Schasinglulu   bootloader will look for a file called ``armstub8.bin`` and load it at
417*91f16700Schasinglulu   address **0x0** instead of a predefined one.
418*91f16700Schasinglulu
419*91f16700Schasinglulu4. To enable the serial port "Mini UART" in Linux, open ``cmdline.txt`` and add
420*91f16700Schasinglulu   ``console=serial0,115200 console=tty1``.
421*91f16700Schasinglulu
422*91f16700Schasinglulu5. Open ``config.txt`` and add the following lines at the end (``enable_uart=1``
423*91f16700Schasinglulu   is only needed to enable debugging through the Mini UART):
424*91f16700Schasinglulu
425*91f16700Schasinglulu::
426*91f16700Schasinglulu
427*91f16700Schasinglulu    enable_uart=1
428*91f16700Schasinglulu    kernel_address=0x02000000
429*91f16700Schasinglulu    device_tree_address=0x01000000
430*91f16700Schasinglulu
431*91f16700SchasingluluIf you connect a serial cable to the Mini UART and your computer, and connect
432*91f16700Schasingluluto it (for example, with ``screen /dev/ttyUSB0 115200``) you should see some
433*91f16700Schasinglulutext. In the case of an AArch32 kernel, you should see something like this:
434*91f16700Schasinglulu
435*91f16700Schasinglulu::
436*91f16700Schasinglulu
437*91f16700Schasinglulu    NOTICE:  Booting Trusted Firmware
438*91f16700Schasinglulu    NOTICE:  BL1: v1.4(release):v1.4-329-g61e94684-dirty
439*91f16700Schasinglulu    NOTICE:  BL1: Built : 00:09:25, Nov  6 2017
440*91f16700Schasinglulu    NOTICE:  BL1: Booting BL2
441*91f16700Schasinglulu    NOTICE:  BL2: v1.4(release):v1.4-329-g61e94684-dirty
442*91f16700Schasinglulu    NOTICE:  BL2: Built : 00:09:25, Nov  6 2017
443*91f16700Schasinglulu    NOTICE:  BL1: Booting BL31
444*91f16700Schasinglulu    NOTICE:  BL31: v1.4(release):v1.4-329-g61e94684-dirty
445*91f16700Schasinglulu    NOTICE:  BL31: Built : 00:09:25, Nov  6 2017
446*91f16700Schasinglulu    [    0.266484] bcm2835-aux-uart 3f215040.serial: could not get clk: -517
447*91f16700Schasinglulu
448*91f16700Schasinglulu    Raspbian GNU/Linux 9 raspberrypi ttyS0
449*91f16700Schasinglulu    raspberrypi login:
450*91f16700Schasinglulu
451*91f16700SchasingluluJust enter your credentials, everything should work as expected. Note that the
452*91f16700SchasingluluHDMI output won't show any text during boot.
453*91f16700Schasinglulu
454*91f16700Schasinglulu.. _default Arm stub: https://github.com/raspberrypi/tools/blob/master/armstubs/armstub7.S
455*91f16700Schasinglulu.. _default AArch64 stub: https://github.com/raspberrypi/tools/blob/master/armstubs/armstub8.S
456*91f16700Schasinglulu.. _Linux kernel tree: https://github.com/torvalds/linux
457*91f16700Schasinglulu.. _Linux tree fork: https://github.com/raspberrypi/linux
458*91f16700Schasinglulu.. _Raspberry Pi 3: https://www.raspberrypi.org/products/raspberry-pi-3-model-b/
459*91f16700Schasinglulu.. _Raspberry Pi 3 TF-A bootstrap: https://github.com/AntonioND/rpi3-arm-tf-bootstrap
460*91f16700Schasinglulu.. _Raspberry Pi 3 documentation: https://www.raspberrypi.org/documentation/
461*91f16700Schasinglulu.. _Raspbian: https://www.raspberrypi.org/downloads/raspbian/
462