Andre Przywara | e6d5fee | 2019-07-22 10:31:10 +0100 | [diff] [blame] | 1 | Raspberry Pi 4 |
| 2 | ============== |
| 3 | |
| 4 | The `Raspberry Pi 4`_ is an inexpensive single-board computer that contains four |
| 5 | Arm Cortex-A72 cores. Also in contrast to previous Raspberry Pi versions this |
| 6 | model has a GICv2 interrupt controller. |
| 7 | |
| 8 | This port is a minimal port to support loading non-secure EL2 payloads such |
| 9 | as a 64-bit Linux kernel. Other payloads such as U-Boot or EDK-II should work |
| 10 | as well, but have not been tested at this point. |
| 11 | |
| 12 | **IMPORTANT NOTE**: This port isn't secure. All of the memory used is DRAM, |
| 13 | which is available from both the Non-secure and Secure worlds. The SoC does |
| 14 | not seem to feature a secure memory controller of any kind, so portions of |
| 15 | DRAM can't be protected properly from the Non-secure world. |
| 16 | |
| 17 | Build Instructions |
| 18 | ------------------ |
| 19 | |
| 20 | There are no real configuration options at this point, so there is only |
| 21 | one universal binary (bl31.bin), which can be built with: |
| 22 | |
| 23 | .. code:: shell |
| 24 | |
| 25 | CROSS_COMPILE=aarch64-linux-gnu- make PLAT=rpi4 DEBUG=1 |
| 26 | |
| 27 | Copy the generated build/rpi4/debug/bl31.bin to the SD card, either |
| 28 | renaming it to ``armstub8.bin`` or adding an entry starting with ``armstub=``, |
| 29 | then followed by the respective file name to ``config.txt``. |
| 30 | You should have AArch64 code in the file loaded as the "kernel", as BL31 |
| 31 | will drop into AArch64/EL2 to the respective load address. |
| 32 | arm64 Linux kernels are known to work this way. |
| 33 | |
| 34 | Other options that should be set in ``config.txt`` to properly boot 64-bit |
| 35 | kernels are: |
| 36 | |
| 37 | :: |
| 38 | |
| 39 | enable_uart=1 |
| 40 | arm_64bit=1 |
| 41 | enable_gic=1 |
| 42 | |
| 43 | The BL31 code will patch the provided device tree blob in memory to advertise |
| 44 | PSCI support, also will add a reserved-memory node to the DT to tell the |
| 45 | non-secure payload to not touch the resident TF-A code. |
| 46 | |
| 47 | If you connect a serial cable between the Mini UART and your computer, and |
| 48 | connect to it (for example, with ``screen /dev/ttyUSB0 115200``) you should |
| 49 | see some text from BL31, followed by the output of the EL2 payload. |
| 50 | The command line provided is read from the ``cmdline.txt`` file on the SD card. |
| 51 | |
| 52 | TF-A port design |
| 53 | ---------------- |
| 54 | |
| 55 | In contrast to the existing Raspberry Pi 3 port this one here is a BL31-only |
| 56 | port, also it deviates quite a lot from the RPi3 port in many other ways. |
| 57 | There is not so much difference between the two models, so eventually those |
| 58 | two could be (more) unified in the future. |
| 59 | |
| 60 | As with the previous models, the GPU and its firmware are the first entity to |
| 61 | run after the SoC gets its power. The on-chip Boot ROM loads the next stage |
| 62 | (bootcode.bin) from flash (EEPROM), which is again GPU code. |
| 63 | This part knows how to access the MMC controller and how to parse a FAT |
| 64 | filesystem, so it will load further compononents and configuration files |
| 65 | from the first FAT partition on the SD card. |
| 66 | |
| 67 | To accommodate this existing way of configuring and setting up the board, |
| 68 | we use as much of this workflow as possible. |
| 69 | If bootcode.bin finds a file called ``armstub8.bin`` on the SD card or it gets |
| 70 | pointed to such code by finding a ``armstub=`` key in ``config.txt``, it will |
| 71 | load this file to the beginning of DRAM (address 0) and execute it in |
| 72 | AArch64 EL3. |
| 73 | But before doing that, it will also load a "kernel" and the device tree into |
| 74 | memory. The load addresses have a default, but can also be changed by |
| 75 | setting them in ``config.txt``. If the GPU firmware finds a magic value in the |
| 76 | armstub image file, it will put those two load addresses in memory locations |
| 77 | near the beginning of memory, where TF-A code picks them up. |
| 78 | |
| 79 | To keep things simple, we will just use the kernel load address as the BL33 |
| 80 | entry point, also put the DTB address in the x0 register, as requested by |
| 81 | the arm64 Linux kernel boot protocol. This does not necessarily mean that |
| 82 | the EL2 payload needs to be a Linux kernel, a bootloader or any other kernel |
| 83 | would work as well, as long as it can cope with having the DT address in |
| 84 | register x0. If the payload has other means of finding the device tree, it |
| 85 | could ignore this address as well. |