Andre Przywara | 32f095d | 2017-04-26 01:32:51 +0100 | [diff] [blame] | 1 | Allwinner 64-bit boards README |
| 2 | ============================== |
| 3 | |
| 4 | Newer Allwinner SoCs feature ARMv8 cores (ARM Cortex-A53) with support for |
| 5 | both the 64-bit AArch64 mode and the ARMv7 compatible 32-bit AArch32 mode. |
| 6 | Examples are the Allwinner A64 (used for instance on the Pine64 board) or |
| 7 | the Allwinner H5 SoC (as used on the OrangePi PC 2). |
| 8 | These SoCs are wired to start in AArch32 mode on reset and execute 32-bit |
| 9 | code from the Boot ROM (BROM). As this has some implications on U-Boot, this |
| 10 | file describes how to make full use of the 64-bit capabilities. |
| 11 | |
| 12 | Quick Start / Overview |
| 13 | ====================== |
| 14 | - Build the ARM Trusted Firmware binary (see "ARM Trusted Firmware (ATF)" below) |
Andre Przywara | a6727be | 2018-12-06 01:25:57 +0000 | [diff] [blame] | 15 | $ cd /src/arm-trusted-firmware |
| 16 | $ make PLAT=sun50i_a64 DEBUG=1 bl31 |
Samuel Holland | 6b7db0a | 2020-10-21 21:12:16 -0500 | [diff] [blame] | 17 | - Build the SCP firmware binary (see "SCP firmware (Crust)" below) |
| 18 | $ cd /src/crust |
| 19 | $ make pine64_plus_defconfig && make -j5 scp |
Andre Przywara | 32f095d | 2017-04-26 01:32:51 +0100 | [diff] [blame] | 20 | - Build U-Boot (see "SPL/U-Boot" below) |
Andre Przywara | a6727be | 2018-12-06 01:25:57 +0000 | [diff] [blame] | 21 | $ export BL31=/path/to/bl31.bin |
Samuel Holland | 6b7db0a | 2020-10-21 21:12:16 -0500 | [diff] [blame] | 22 | $ export SCP=/src/crust/build/scp/scp.bin |
Andre Przywara | a6727be | 2018-12-06 01:25:57 +0000 | [diff] [blame] | 23 | $ make pine64_plus_defconfig && make -j5 |
Andre Przywara | 32f095d | 2017-04-26 01:32:51 +0100 | [diff] [blame] | 24 | - Transfer to an uSD card (see "microSD card" below) |
Andre Przywara | a6727be | 2018-12-06 01:25:57 +0000 | [diff] [blame] | 25 | $ dd if=u-boot-sunxi-with-spl.bin of=/dev/sdx bs=8k seek=1 |
Andre Przywara | 32f095d | 2017-04-26 01:32:51 +0100 | [diff] [blame] | 26 | - Boot and enjoy! |
| 27 | |
| 28 | Building the firmware |
| 29 | ===================== |
| 30 | |
Samuel Holland | 6b7db0a | 2020-10-21 21:12:16 -0500 | [diff] [blame] | 31 | The Allwinner A64/H5/H6 firmware consists of several parts: U-Boot's SPL, |
| 32 | ARM Trusted Firmware (ATF), optional System Control Processor (SCP) firmware |
| 33 | (e.g. Crust), and the U-Boot proper. |
| 34 | |
| 35 | The SPL will load all of the other firmware binaries into RAM, along with the |
| 36 | right device tree blob (.dtb), and will pass execution to ATF (in EL3). If SCP |
| 37 | firmware was loaded, ATF will power on the SCP and wait for it to boot. |
| 38 | ATF will then drop into U-Boot proper (in EL2). |
| 39 | |
| 40 | As the ATF binary and SCP firmware will become part of the U-Boot image file, |
| 41 | you will need to build them first. |
Andre Przywara | 32f095d | 2017-04-26 01:32:51 +0100 | [diff] [blame] | 42 | |
| 43 | ARM Trusted Firmware (ATF) |
| 44 | ---------------------------- |
Andre Przywara | a6727be | 2018-12-06 01:25:57 +0000 | [diff] [blame] | 45 | Checkout the latest master branch from the official ATF repository [1] and |
| 46 | build it: |
Andre Przywara | 32f095d | 2017-04-26 01:32:51 +0100 | [diff] [blame] | 47 | $ export CROSS_COMPILE=aarch64-linux-gnu- |
Andre Przywara | a6727be | 2018-12-06 01:25:57 +0000 | [diff] [blame] | 48 | $ make PLAT=sun50i_a64 DEBUG=1 bl31 |
| 49 | The resulting binary is build/sun50i_a64/debug/bl31.bin. Either put the |
Andre Przywara | 32f095d | 2017-04-26 01:32:51 +0100 | [diff] [blame] | 50 | location of this file into the BL31 environment variable or copy this to |
| 51 | the root of your U-Boot build directory (or create a symbolic link). |
Andre Przywara | a6727be | 2018-12-06 01:25:57 +0000 | [diff] [blame] | 52 | $ export BL31=/src/arm-trusted-firmware/build/sun50i_a64/debug/bl31.bin |
Andre Przywara | 32f095d | 2017-04-26 01:32:51 +0100 | [diff] [blame] | 53 | (adjust the actual path accordingly) |
Andre Przywara | a6727be | 2018-12-06 01:25:57 +0000 | [diff] [blame] | 54 | The platform target "sun50i_a64" covers all boards with either an Allwinner |
| 55 | A64 or H5 SoC (since they are very similar). For boards with an Allwinner H6 |
| 56 | SoC use "sun50i_h6". |
Andre Przywara | 32f095d | 2017-04-26 01:32:51 +0100 | [diff] [blame] | 57 | |
Andre Przywara | 1dfb7d4 | 2018-04-04 01:31:13 +0100 | [diff] [blame] | 58 | If you run into size issues with the resulting U-Boot image file, it might |
| 59 | help to use a release build, by using "DEBUG=0" when building bl31.bin. |
| 60 | As sometimes the ATF build process is a bit picky about the toolchain used, |
| 61 | or if you can't be bothered with building ATF, there are known working |
| 62 | binaries in the firmware repository[3], purely for convenience reasons. |
| 63 | |
Samuel Holland | 6b7db0a | 2020-10-21 21:12:16 -0500 | [diff] [blame] | 64 | SCP firmware (Crust) |
| 65 | ---------------------- |
| 66 | SCP firmware is responsible for implementing system suspend/resume, and (on |
| 67 | boards without a PMIC) soft poweroff/on. ATF contains fallback code for CPU |
| 68 | power control, so SCP firmware is optional if you don't need either of these |
| 69 | features. It runs on the AR100, with is an or1k CPU, not ARM, so it needs a |
| 70 | different cross toolchain. |
| 71 | |
| 72 | There is one SCP firmware implementation currently available, Crust: |
| 73 | $ git clone https://github.com/crust-firmware/crust |
| 74 | $ cd crust |
| 75 | $ export CROSS_COMPILE=or1k-linux-musl- |
| 76 | $ make pine64_plus_defconfig |
| 77 | $ make scp |
| 78 | |
| 79 | The same configuration generally works on any board with the same SoC (A64, H5, |
| 80 | or H6), so if there is no config for your board, use one for a similar board. |
| 81 | |
| 82 | Like for ATF, U-Boot finds the SCP firmware binary via an environment variable: |
| 83 | $ export SCP=/src/crust/build/scp/scp.bin |
| 84 | |
| 85 | If you do not want to use SCP firmware, you can silence the warning from binman |
| 86 | by pointing it to an empty file: |
| 87 | $ export SCP=/dev/null |
| 88 | |
Andre Przywara | 32f095d | 2017-04-26 01:32:51 +0100 | [diff] [blame] | 89 | SPL/U-Boot |
| 90 | ------------ |
| 91 | Both U-Boot proper and the SPL are using the 64-bit mode. As the boot ROM |
| 92 | enters the SPL still in AArch32 secure SVC mode, there is some shim code to |
| 93 | enter AArch64 very early. The rest of the SPL runs in AArch64 EL3. |
| 94 | U-Boot proper runs in EL2 and can load any AArch64 code (using the "go" |
| 95 | command), EFI applications (with "bootefi") or arm64 Linux kernel images |
| 96 | (often named "Image"), using the "booti" command. |
| 97 | |
| 98 | $ make clean |
| 99 | $ export CROSS_COMPILE=aarch64-linux-gnu- |
| 100 | $ make pine64_plus_defconfig |
| 101 | $ make |
| 102 | |
| 103 | This will build the SPL in spl/sunxi-spl.bin and a FIT image called u-boot.itb, |
Andre Przywara | a6727be | 2018-12-06 01:25:57 +0000 | [diff] [blame] | 104 | which contains the rest of the firmware. u-boot-sunxi-with-spl.bin joins those |
| 105 | two components in one convenient image file. |
Andre Przywara | 32f095d | 2017-04-26 01:32:51 +0100 | [diff] [blame] | 106 | |
| 107 | |
| 108 | Boot process |
| 109 | ============ |
| 110 | The on-die BROM code will try several methods to load and execute the firmware. |
| 111 | On a typical board like the Pine64 this will result in the following boot order: |
| 112 | |
| 113 | 1) Reading 32KB from sector 16 (@8K) of the microSD card to SRAM A1. If the |
| 114 | BROM finds the magic "eGON" header in the first bytes, it will execute that |
| 115 | code. If not (no SD card at all or invalid magic), it will: |
| 116 | 2) Try to read 32KB from sector 16 (@8K) of memory connected to the MMC2 |
| 117 | controller, typically an on-board eMMC chip. If there is no eMMC or it does |
| 118 | not contain a valid boot header, it will: |
| 119 | 3) Initialize the SPI0 controller and try to access a NOR flash connected to |
| 120 | it (using the CS0 pin). If a flash chip is found, the BROM will load the |
| 121 | first 32KB (from offset 0) into SRAM A1. Now it checks for the magic eGON |
| 122 | header and checksum and will execute the code upon finding it. If not, it will: |
| 123 | 4) Initialize the USB OTG controller and will wait for a host to connect to |
| 124 | it, speaking the Allwinner proprietary (but deciphered) "FEL" USB protocol. |
| 125 | |
| 126 | |
| 127 | To boot the Pine64 board, you can use U-Boot and any of the described methods. |
| 128 | |
| 129 | FEL boot (USB OTG) |
| 130 | ------------------ |
| 131 | FEL is the name of the Allwinner defined USB boot protocol built in the |
| 132 | mask ROM of most Allwinner SoCs. It allows to bootstrap a board solely |
| 133 | by using the USB-OTG interface and a host port on another computer. |
| 134 | As the FEL mode is controlled by the boot ROM, it expects to be running in |
| 135 | AArch32. For now the AArch64 SPL cannot properly return into FEL mode, so the |
| 136 | feature is disabled in the configuration at the moment. |
Andre Przywara | a6727be | 2018-12-06 01:25:57 +0000 | [diff] [blame] | 137 | The repository in [3] contains FEL capable SPL binaries, built using an |
| 138 | off-tree branch to generate 32-bit ARM code (along with instructions |
| 139 | how to re-create them). |
Andre Przywara | 32f095d | 2017-04-26 01:32:51 +0100 | [diff] [blame] | 140 | |
| 141 | microSD card |
| 142 | ------------ |
| 143 | Transfer the SPL and the U-Boot FIT image directly to an uSD card: |
| 144 | # dd if=spl/sunxi-spl.bin of=/dev/sdx bs=8k seek=1 |
| 145 | # dd if=u-boot.itb of=/dev/sdx bs=8k seek=5 |
| 146 | # sync |
| 147 | (replace /dev/sdx with you SD card device file name, which could be |
| 148 | /dev/mmcblk[x] as well). |
| 149 | |
Tuomas Tynkkynen | c0c3d2b | 2018-03-06 23:38:22 +0200 | [diff] [blame] | 150 | Alternatively you can use the SPL and the U-Boot FIT image combined into a |
Andre Przywara | 32f095d | 2017-04-26 01:32:51 +0100 | [diff] [blame] | 151 | single file and transfer that instead: |
Andre Przywara | 32f095d | 2017-04-26 01:32:51 +0100 | [diff] [blame] | 152 | # dd if=u-boot-sunxi-with-spl.bin of=/dev/sdx bs=8k seek=1 |
| 153 | |
| 154 | You can partition the microSD card, but leave the first MB unallocated (most |
| 155 | partitioning tools will do this anyway). |
| 156 | |
| 157 | NOR flash |
| 158 | --------- |
| 159 | Some boards (like the SoPine, Pinebook or the OrangePi PC2) come with a |
| 160 | soldered SPI NOR flash chip. On other boards like the Pine64 such a chip |
| 161 | can be connected to the SPI0/CS0 pins on the PI-2 headers. |
| 162 | Create the SPL and FIT image like described above for the SD card. |
| 163 | Now connect either an "A to A" USB cable to the upper USB port on the Pine64 |
| 164 | or get an adaptor and use a regular A-microB cable connected to it. Other |
| 165 | boards often have a proper micro-B USB socket connected to the USB OTB port. |
| 166 | Remove a microSD card from the slot and power on the board. |
| 167 | On your host computer download and build the sunxi-tools package[2], then |
| 168 | use "sunxi-fel" to access the board: |
| 169 | $ ./sunxi-fel ver -v -p |
| 170 | This should give you an output starting with: AWUSBFEX soc=00001689(A64) ... |
| 171 | Now use the sunxi-fel tool to write to the NOR flash: |
| 172 | $ ./sunxi-fel spiflash-write 0 spl/sunxi-spl.bin |
| 173 | $ ./sunxi-fel spiflash-write 32768 u-boot.itb |
| 174 | Now boot the board without an SD card inserted and you should see the |
| 175 | U-Boot prompt on the serial console. |
| 176 | |
| 177 | (Legacy) boot0 method |
| 178 | --------------------- |
Priit Laes | cb9325d | 2018-10-23 20:20:28 +0300 | [diff] [blame] | 179 | boot0 is Allwinner's secondary program loader and it can be used as some kind |
Andre Przywara | 32f095d | 2017-04-26 01:32:51 +0100 | [diff] [blame] | 180 | of SPL replacement to get U-Boot up and running from an microSD card. |
| 181 | For some time using boot0 was the only option to get the Pine64 booted. |
| 182 | With working DRAM init code in U-Boot's SPL this is no longer necessary, |
| 183 | but this method is described here for the sake of completeness. |
| 184 | Please note that this method works only with the boot0 files shipped with |
| 185 | A64 based boards, the H5 uses an incompatible layout which is not supported |
| 186 | by this method. |
| 187 | |
| 188 | The boot0 binary is a 32 KByte blob and contained in the official Pine64 images |
| 189 | distributed by Pine64 or Allwinner. It can be easily extracted from a micro |
| 190 | SD card or an image file: |
| 191 | # dd if=/dev/sd<x> of=boot0.bin bs=8k skip=1 count=4 |
| 192 | where /dev/sd<x> is the device name of the uSD card or the name of the image |
| 193 | file. Apparently Allwinner allows re-distribution of this proprietary code |
| 194 | "as-is". |
| 195 | This boot0 blob takes care of DRAM initialisation and loads the remaining |
| 196 | firmware parts, then switches the core into AArch64 mode. |
| 197 | The original boot0 code looks for U-Boot at a certain place on an uSD card |
| 198 | (at 19096 KB), also it expects a header with magic bytes and a checksum. |
| 199 | There is a tool called boot0img[3] which takes a boot0.bin image and a compiled |
| 200 | U-Boot binary (plus other binaries) and will populate that header accordingly. |
| 201 | To make space for the magic header, the pine64_plus_defconfig will make sure |
| 202 | there is sufficient space at the beginning of the U-Boot binary. |
| 203 | boot0img will also take care of putting the different binaries at the right |
| 204 | places on the uSD card and works around unused, but mandatory parts by using |
| 205 | trampoline code. See the output of "boot0img -h" for more information. |
| 206 | boot0img can also patch boot0 to avoid loading U-Boot from 19MB, instead |
| 207 | fetching it from just behind the boot0 binary (-B option). |
| 208 | $ ./boot0img -o firmware.img -B boot0.img -u u-boot-dtb.bin -e -s bl31.bin \ |
| 209 | -a 0x44008 -d trampoline64:0x44000 |
| 210 | Then write this image to a microSD card, replacing /dev/sdx with the right |
| 211 | device file (see above): |
| 212 | $ dd if=firmware.img of=/dev/sdx bs=8k seek=1 |
| 213 | |
Andre Przywara | a6727be | 2018-12-06 01:25:57 +0000 | [diff] [blame] | 214 | [1] https://github.com/ARM-software/arm-trusted-firmware.git |
Andre Przywara | 32f095d | 2017-04-26 01:32:51 +0100 | [diff] [blame] | 215 | [2] git://github.com/linux-sunxi/sunxi-tools.git |
| 216 | [3] https://github.com/apritzel/pine64/ |