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