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