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