1*4882a593SmuzhiyunAllwinner 64-bit boards README 2*4882a593Smuzhiyun============================== 3*4882a593Smuzhiyun 4*4882a593SmuzhiyunNewer Allwinner SoCs feature ARMv8 cores (ARM Cortex-A53) with support for 5*4882a593Smuzhiyunboth the 64-bit AArch64 mode and the ARMv7 compatible 32-bit AArch32 mode. 6*4882a593SmuzhiyunExamples are the Allwinner A64 (used for instance on the Pine64 board) or 7*4882a593Smuzhiyunthe Allwinner H5 SoC (as used on the OrangePi PC 2). 8*4882a593SmuzhiyunThese SoCs are wired to start in AArch32 mode on reset and execute 32-bit 9*4882a593Smuzhiyuncode from the Boot ROM (BROM). As this has some implications on U-Boot, this 10*4882a593Smuzhiyunfile describes how to make full use of the 64-bit capabilities. 11*4882a593Smuzhiyun 12*4882a593SmuzhiyunQuick Start / Overview 13*4882a593Smuzhiyun====================== 14*4882a593Smuzhiyun- Build the ARM Trusted Firmware binary (see "ARM Trusted Firmware (ATF)" below) 15*4882a593Smuzhiyun- Build U-Boot (see "SPL/U-Boot" below) 16*4882a593Smuzhiyun- Transfer to an uSD card (see "microSD card" below) 17*4882a593Smuzhiyun- Boot and enjoy! 18*4882a593Smuzhiyun 19*4882a593SmuzhiyunBuilding the firmware 20*4882a593Smuzhiyun===================== 21*4882a593Smuzhiyun 22*4882a593SmuzhiyunThe Allwinner A64/H5 firmware consists of three parts: U-Boot's SPL, an 23*4882a593SmuzhiyunARM Trusted Firmware (ATF) build and the U-Boot proper. 24*4882a593SmuzhiyunThe SPL will load both ATF and U-Boot proper along with the right device 25*4882a593Smuzhiyuntree blob (.dtb) and will pass execution to ATF (in EL3), which in turn will 26*4882a593Smuzhiyundrop into the U-Boot proper (in EL2). 27*4882a593SmuzhiyunAs the ATF binary will become part of the U-Boot image file, you will need 28*4882a593Smuzhiyunto build it first. 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun ARM Trusted Firmware (ATF) 31*4882a593Smuzhiyun---------------------------- 32*4882a593SmuzhiyunCheckout the "allwinner" branch from the github repository [1] and build it: 33*4882a593Smuzhiyun$ export CROSS_COMPILE=aarch64-linux-gnu- 34*4882a593Smuzhiyun$ make PLAT=sun50iw1p1 DEBUG=1 bl31 35*4882a593SmuzhiyunThe resulting binary is build/sun50iw1p1/debug/bl31.bin. Either put the 36*4882a593Smuzhiyunlocation of this file into the BL31 environment variable or copy this to 37*4882a593Smuzhiyunthe root of your U-Boot build directory (or create a symbolic link). 38*4882a593Smuzhiyun$ export BL31=/src/arm-trusted-firmware/build/sun50iw1p1/debug/bl31.bin 39*4882a593Smuzhiyun (adjust the actual path accordingly) 40*4882a593Smuzhiyun 41*4882a593Smuzhiyun SPL/U-Boot 42*4882a593Smuzhiyun------------ 43*4882a593SmuzhiyunBoth U-Boot proper and the SPL are using the 64-bit mode. As the boot ROM 44*4882a593Smuzhiyunenters the SPL still in AArch32 secure SVC mode, there is some shim code to 45*4882a593Smuzhiyunenter AArch64 very early. The rest of the SPL runs in AArch64 EL3. 46*4882a593SmuzhiyunU-Boot proper runs in EL2 and can load any AArch64 code (using the "go" 47*4882a593Smuzhiyuncommand), EFI applications (with "bootefi") or arm64 Linux kernel images 48*4882a593Smuzhiyun(often named "Image"), using the "booti" command. 49*4882a593Smuzhiyun 50*4882a593Smuzhiyun$ make clean 51*4882a593Smuzhiyun$ export CROSS_COMPILE=aarch64-linux-gnu- 52*4882a593Smuzhiyun$ make pine64_plus_defconfig 53*4882a593Smuzhiyun$ make 54*4882a593Smuzhiyun 55*4882a593SmuzhiyunThis will build the SPL in spl/sunxi-spl.bin and a FIT image called u-boot.itb, 56*4882a593Smuzhiyunwhich contains the rest of the firmware. 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun 59*4882a593SmuzhiyunBoot process 60*4882a593Smuzhiyun============ 61*4882a593SmuzhiyunThe on-die BROM code will try several methods to load and execute the firmware. 62*4882a593SmuzhiyunOn a typical board like the Pine64 this will result in the following boot order: 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun1) Reading 32KB from sector 16 (@8K) of the microSD card to SRAM A1. If the 65*4882a593SmuzhiyunBROM finds the magic "eGON" header in the first bytes, it will execute that 66*4882a593Smuzhiyuncode. If not (no SD card at all or invalid magic), it will: 67*4882a593Smuzhiyun2) Try to read 32KB from sector 16 (@8K) of memory connected to the MMC2 68*4882a593Smuzhiyuncontroller, typically an on-board eMMC chip. If there is no eMMC or it does 69*4882a593Smuzhiyunnot contain a valid boot header, it will: 70*4882a593Smuzhiyun3) Initialize the SPI0 controller and try to access a NOR flash connected to 71*4882a593Smuzhiyunit (using the CS0 pin). If a flash chip is found, the BROM will load the 72*4882a593Smuzhiyunfirst 32KB (from offset 0) into SRAM A1. Now it checks for the magic eGON 73*4882a593Smuzhiyunheader and checksum and will execute the code upon finding it. If not, it will: 74*4882a593Smuzhiyun4) Initialize the USB OTG controller and will wait for a host to connect to 75*4882a593Smuzhiyunit, speaking the Allwinner proprietary (but deciphered) "FEL" USB protocol. 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun 78*4882a593SmuzhiyunTo boot the Pine64 board, you can use U-Boot and any of the described methods. 79*4882a593Smuzhiyun 80*4882a593SmuzhiyunFEL boot (USB OTG) 81*4882a593Smuzhiyun------------------ 82*4882a593SmuzhiyunFEL is the name of the Allwinner defined USB boot protocol built in the 83*4882a593Smuzhiyunmask ROM of most Allwinner SoCs. It allows to bootstrap a board solely 84*4882a593Smuzhiyunby using the USB-OTG interface and a host port on another computer. 85*4882a593SmuzhiyunAs the FEL mode is controlled by the boot ROM, it expects to be running in 86*4882a593SmuzhiyunAArch32. For now the AArch64 SPL cannot properly return into FEL mode, so the 87*4882a593Smuzhiyunfeature is disabled in the configuration at the moment. 88*4882a593Smuzhiyun 89*4882a593SmuzhiyunmicroSD card 90*4882a593Smuzhiyun------------ 91*4882a593SmuzhiyunTransfer the SPL and the U-Boot FIT image directly to an uSD card: 92*4882a593Smuzhiyun# dd if=spl/sunxi-spl.bin of=/dev/sdx bs=8k seek=1 93*4882a593Smuzhiyun# dd if=u-boot.itb of=/dev/sdx bs=8k seek=5 94*4882a593Smuzhiyun# sync 95*4882a593Smuzhiyun(replace /dev/sdx with you SD card device file name, which could be 96*4882a593Smuzhiyun/dev/mmcblk[x] as well). 97*4882a593Smuzhiyun 98*4882a593SmuzhiyunAlternatively you can concatenate the SPL and the U-Boot FIT image into a 99*4882a593Smuzhiyunsingle file and transfer that instead: 100*4882a593Smuzhiyun$ cat spl/sunxi-spl.bin u-boot.itb > u-boot-sunxi-with-spl.bin 101*4882a593Smuzhiyun# dd if=u-boot-sunxi-with-spl.bin of=/dev/sdx bs=8k seek=1 102*4882a593Smuzhiyun 103*4882a593SmuzhiyunYou can partition the microSD card, but leave the first MB unallocated (most 104*4882a593Smuzhiyunpartitioning tools will do this anyway). 105*4882a593Smuzhiyun 106*4882a593SmuzhiyunNOR flash 107*4882a593Smuzhiyun--------- 108*4882a593SmuzhiyunSome boards (like the SoPine, Pinebook or the OrangePi PC2) come with a 109*4882a593Smuzhiyunsoldered SPI NOR flash chip. On other boards like the Pine64 such a chip 110*4882a593Smuzhiyuncan be connected to the SPI0/CS0 pins on the PI-2 headers. 111*4882a593SmuzhiyunCreate the SPL and FIT image like described above for the SD card. 112*4882a593SmuzhiyunNow connect either an "A to A" USB cable to the upper USB port on the Pine64 113*4882a593Smuzhiyunor get an adaptor and use a regular A-microB cable connected to it. Other 114*4882a593Smuzhiyunboards often have a proper micro-B USB socket connected to the USB OTB port. 115*4882a593SmuzhiyunRemove a microSD card from the slot and power on the board. 116*4882a593SmuzhiyunOn your host computer download and build the sunxi-tools package[2], then 117*4882a593Smuzhiyunuse "sunxi-fel" to access the board: 118*4882a593Smuzhiyun$ ./sunxi-fel ver -v -p 119*4882a593SmuzhiyunThis should give you an output starting with: AWUSBFEX soc=00001689(A64) ... 120*4882a593SmuzhiyunNow use the sunxi-fel tool to write to the NOR flash: 121*4882a593Smuzhiyun$ ./sunxi-fel spiflash-write 0 spl/sunxi-spl.bin 122*4882a593Smuzhiyun$ ./sunxi-fel spiflash-write 32768 u-boot.itb 123*4882a593SmuzhiyunNow boot the board without an SD card inserted and you should see the 124*4882a593SmuzhiyunU-Boot prompt on the serial console. 125*4882a593Smuzhiyun 126*4882a593Smuzhiyun(Legacy) boot0 method 127*4882a593Smuzhiyun--------------------- 128*4882a593Smuzhiyunboot0 is Allwiner's secondary program loader and it can be used as some kind 129*4882a593Smuzhiyunof SPL replacement to get U-Boot up and running from an microSD card. 130*4882a593SmuzhiyunFor some time using boot0 was the only option to get the Pine64 booted. 131*4882a593SmuzhiyunWith working DRAM init code in U-Boot's SPL this is no longer necessary, 132*4882a593Smuzhiyunbut this method is described here for the sake of completeness. 133*4882a593SmuzhiyunPlease note that this method works only with the boot0 files shipped with 134*4882a593SmuzhiyunA64 based boards, the H5 uses an incompatible layout which is not supported 135*4882a593Smuzhiyunby this method. 136*4882a593Smuzhiyun 137*4882a593SmuzhiyunThe boot0 binary is a 32 KByte blob and contained in the official Pine64 images 138*4882a593Smuzhiyundistributed by Pine64 or Allwinner. It can be easily extracted from a micro 139*4882a593SmuzhiyunSD card or an image file: 140*4882a593Smuzhiyun# dd if=/dev/sd<x> of=boot0.bin bs=8k skip=1 count=4 141*4882a593Smuzhiyunwhere /dev/sd<x> is the device name of the uSD card or the name of the image 142*4882a593Smuzhiyunfile. Apparently Allwinner allows re-distribution of this proprietary code 143*4882a593Smuzhiyun"as-is". 144*4882a593SmuzhiyunThis boot0 blob takes care of DRAM initialisation and loads the remaining 145*4882a593Smuzhiyunfirmware parts, then switches the core into AArch64 mode. 146*4882a593SmuzhiyunThe original boot0 code looks for U-Boot at a certain place on an uSD card 147*4882a593Smuzhiyun(at 19096 KB), also it expects a header with magic bytes and a checksum. 148*4882a593SmuzhiyunThere is a tool called boot0img[3] which takes a boot0.bin image and a compiled 149*4882a593SmuzhiyunU-Boot binary (plus other binaries) and will populate that header accordingly. 150*4882a593SmuzhiyunTo make space for the magic header, the pine64_plus_defconfig will make sure 151*4882a593Smuzhiyunthere is sufficient space at the beginning of the U-Boot binary. 152*4882a593Smuzhiyunboot0img will also take care of putting the different binaries at the right 153*4882a593Smuzhiyunplaces on the uSD card and works around unused, but mandatory parts by using 154*4882a593Smuzhiyuntrampoline code. See the output of "boot0img -h" for more information. 155*4882a593Smuzhiyunboot0img can also patch boot0 to avoid loading U-Boot from 19MB, instead 156*4882a593Smuzhiyunfetching it from just behind the boot0 binary (-B option). 157*4882a593Smuzhiyun$ ./boot0img -o firmware.img -B boot0.img -u u-boot-dtb.bin -e -s bl31.bin \ 158*4882a593Smuzhiyun-a 0x44008 -d trampoline64:0x44000 159*4882a593SmuzhiyunThen write this image to a microSD card, replacing /dev/sdx with the right 160*4882a593Smuzhiyundevice file (see above): 161*4882a593Smuzhiyun$ dd if=firmware.img of=/dev/sdx bs=8k seek=1 162*4882a593Smuzhiyun 163*4882a593Smuzhiyun[1] https://github.com/apritzel/arm-trusted-firmware.git 164*4882a593Smuzhiyun[2] git://github.com/linux-sunxi/sunxi-tools.git 165*4882a593Smuzhiyun[3] https://github.com/apritzel/pine64/ 166