Andre Przywara | eaaa5fb | 2021-12-27 15:07:36 +0000 | [diff] [blame] | 1 | .. SPDX-License-Identifier: GPL-2.0+ |
| 2 | .. Copyright (C) 2021 Arm Ltd. |
| 3 | |
| 4 | Allwinner SoC based boards |
| 5 | ========================== |
| 6 | For boards using an Allwinner ARM based SoC ("sunxi"), the U-Boot build |
| 7 | system generates a single integrated image file: ``u-boot-sunxi-with-spl.bin.`` |
| 8 | This file can be used on SD cards, eMMC devices, SPI flash and for the |
| 9 | USB-OTG based boot method (FEL). To build this file: |
| 10 | |
| 11 | * For 64-bit SoCs, build Trusted Firmware (TF-A, formerly known as ATF) first, |
| 12 | you will need its ``bl31.bin``. See below for more details. |
| 13 | * Optionally on 64-bit SoCs, build the `crust`_ management processor firmware, |
| 14 | you will need its ``scp.bin``. See below for more details. |
| 15 | * Build U-Boot:: |
| 16 | |
| 17 | $ export BL31=/path/to/bl31.bin # required for 64-bit SoCs |
| 18 | $ export SCP=/path/to/scp.bin # optional for some 64-bit SoCs |
| 19 | $ make <yourboardname>_defconfig |
| 20 | $ make |
| 21 | * Transfer to an (micro)SD card (see below for more details):: |
| 22 | |
| 23 | $ sudo dd if=u-boot-sunxi-with-spl.bin of=/dev/sdX bs=8k seek=1 |
| 24 | * Boot and enjoy! |
| 25 | |
| 26 | .. note:: |
| 27 | The traditional SD card location the Allwinner BootROM loads from is 8KB |
| 28 | (sector 16). This works fine with the old MBR partitioning scheme, which most |
| 29 | SD cards come formatted with. However this is in the middle of a potential |
| 30 | GPT partition table, which will become invalid in this step. Newer SoCs |
| 31 | (starting with the H3 from late 2014) also support booting from 128KB, which |
| 32 | is beyond even a GPT and thus a safer location. |
| 33 | |
| 34 | For more details, and alternative boot locations or installations, see below. |
| 35 | |
| 36 | Building Arm Trusted Firmware (TF-A) |
| 37 | ------------------------------------ |
| 38 | Boards using a 64-bit Soc (A64, H5, H6, H616, R329) require the BL31 stage of |
| 39 | the `Arm Trusted Firmware-A`_ firmware. This provides the reference |
| 40 | implementation of secure software for Armv8-A, offering PSCI and SMCCC |
| 41 | services. Allwinner support is fully mainlined. To build bl31.bin:: |
| 42 | |
| 43 | $ git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git |
| 44 | $ cd trusted-firmware-a |
| 45 | $ make CROSS_COMPILE=aarch64-linux-gnu- PLAT=sun50i_a64 DEBUG=1 |
| 46 | $ export BL31=$(pwd)/build/sun50i_a64/debug/bl31.bin |
| 47 | |
| 48 | The target platform (``PLAT=``) for A64 and H5 SoCs is sun50i_a64, for the H6 |
| 49 | sun50i_h6, for the H616 sun50i_h616, and for the R329 sun50i_r329. Use:: |
| 50 | |
| 51 | $ find plat/allwinner -name platform.mk |
| 52 | |
| 53 | to find all supported platforms. TF-A's `docs/plat/allwinner.rst`_ contains |
| 54 | more information and lists some build options. |
| 55 | |
| 56 | Building the Crust management processor firmware |
| 57 | ------------------------------------------------ |
| 58 | For some SoCs and boards, the integrated OpenRISC management controller can |
| 59 | be used to provide power management services, foremost suspend to RAM. |
| 60 | There is a community supported Open Source implementation called `crust`_, |
| 61 | which runs on most SoCs featuring a management controller. |
| 62 | |
| 63 | This firmware part is optional, setting the SCP environment variable to |
| 64 | /dev/null avoids the warning message when building without one. |
| 65 | |
| 66 | To build crust's scp.bin, you need an OpenRISC (or1k) cross compiler, then:: |
| 67 | |
| 68 | $ git clone https://github.com/crust-firmware/crust.git |
| 69 | $ cd crust |
| 70 | $ make <yourboard>_defconfig |
| 71 | $ make CROSS_COMPILE=or1k-none-elf- scp |
| 72 | $ export SCP=$(pwd)/build/scp/scp.bin |
| 73 | |
| 74 | Find a list of supported board configurations in the `configs/`_ directory. |
| 75 | The `crust README`_ has more information about the building process, including |
| 76 | information about where to get OpenRISC cross compilers. |
| 77 | |
| 78 | Building the U-Boot image |
| 79 | ------------------------- |
| 80 | Find the U-Boot defconfig file for your board first. Those files live in |
| 81 | the ``configs/`` directory; you can grep for the stub name of the devicetree |
| 82 | file, if you know that, or for the SoC name to find the right version:: |
| 83 | |
| 84 | $ git grep -l MACH_SUN8I_H3 configs |
| 85 | $ git grep -l sun50i-h6-orangepi-3 configs |
| 86 | |
| 87 | The `linux-sunxi`_ wiki also lists the name of the defconfig file in the |
| 88 | respective board page. Then use this defconfig file to create the .config |
| 89 | file, and build the image:: |
| 90 | |
| 91 | $ make <yourboard>_defconfig |
| 92 | $ make |
| 93 | |
| 94 | For 64-bit boards, this requires either the BL31 environment variable to be |
| 95 | set (as shown above in the TF-A build example), or it to be supplied on the |
| 96 | build command line:: |
| 97 | |
| 98 | $ make BL31=/src/tf-a.git/build/sun50i_h616/debug/bl31.bin |
| 99 | |
| 100 | The same applies to the (optional) SCP firmware. |
| 101 | |
| 102 | The file containing everything you need is called ``u-boot-sunxi-with-spl.bin``, |
| 103 | you will find it in the root folder of your U-Boot (build) tree. Except for |
| 104 | raw NAND flash devices this very same file can be used for any boot source. |
| 105 | It will contain the SPL image, fitted with the proper signature recognised by |
| 106 | the BROM, and the required checksum. Also it will contain at least U-Boot |
| 107 | proper, either wrapped in the legacy U-Boot image format, or in a FIT image. |
| 108 | The board's devicetree is also included, either appended to the U-Boot proper |
| 109 | image, or contained in the FIT image. If required by the SoC, this FIT file will |
| 110 | also include the other firmware images. |
| 111 | |
| 112 | Installing U-Boot |
| 113 | ----------------- |
| 114 | |
| 115 | Installing on a (micro-) SD card |
| 116 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 117 | All Allwinner SoCs will try to find a boot image at sector 16 (8KB) of |
| 118 | an SD card, connected to the first MMC controller. To transfer the generated |
| 119 | image to an SD card, from any Linux device (including the board itself) with |
| 120 | an (micro-)SD card reader, type:: |
| 121 | |
| 122 | $ sudo dd if=u-boot-sunxi-with-spl.bin of=/dev/sdX bs=1k seek=8 |
| 123 | |
| 124 | ``/dev/sdx`` needs to be replaced with the block device name of the SD card |
| 125 | reader. On some machines this could be ``/dev/mmcblkX``. |
| 126 | Newer SoCs (starting from the H3 from 2014, and including all ARM64 SoCs), |
| 127 | also look at sector 256 (128KB) for the signature (after having checked the |
| 128 | 8KB location). Installing the firmware there has the advantage of not |
| 129 | overlapping with a GPT partition table. Simply replace the "``seek=8``" above |
| 130 | with "``seek=128``". |
| 131 | |
| 132 | You can also use an existing (mainline) U-Boot to write to the SD card. Load |
| 133 | the generated U-Boot image somewhere into DRAM (via ``ext4load``, ``fatload``, |
| 134 | or ``tftpboot``), then write to MMC device 0:: |
| 135 | |
| 136 | => fatload mmc 0:1 $kernel_addr_r u-boot-sunxi-with-spl.bin |
| 137 | => mmc dev 0 |
| 138 | => mmc write $kernel_addr_r 0x10 0x7f0 |
| 139 | |
| 140 | To use the alternative boot location on newer SoCs:: |
| 141 | |
| 142 | => mmc write $kernel_addr_r 0x100 0x700 |
| 143 | |
| 144 | Installing on eMMC (on-board flash memory) |
| 145 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 146 | Some boards have a soldered eMMC chip, some other boards have an eMMC socket |
| 147 | to receive an optional eMMC module. U-Boot can be installed to those chips, |
| 148 | to boot without an SD card inserted. The Boot-ROM can boot either from the |
| 149 | regular user data partition, or from one of the separate eMMC boot partitions. |
| 150 | U-Boot can be installed either from a running Linux instance on the device, |
| 151 | from a running (mainline) U-Boot, or via an adapter for the (removable) |
| 152 | eMMC module. |
| 153 | |
| 154 | Installing on an eMMC user data partition from Linux |
| 155 | ```````````````````````````````````````````````````` |
| 156 | If you have a running Linux instance on the device, and have somehow copied |
| 157 | over the image file to that device, you can write the image directly into the |
| 158 | eMMC device from there. |
| 159 | Find the name of the block device file first, it is one of the |
| 160 | ``/dev/mmcblk<X>`` devices. eMMC devices typically also list a |
| 161 | ``/dev/mmcblk<X>boot0`` partition (see below), this helps you to tell it apart |
| 162 | from the SD card device. |
| 163 | To install onto the user data partition:: |
| 164 | |
| 165 | $ sudo dd if=u-boot-sunxi-with-spl.bin of=/dev/dev/mmcblkX bs=1k seek=8 |
| 166 | |
| 167 | Similar to SD cards, the BROM in newer SoCs (H3 and above) also checks |
| 168 | sector 256 of an eMMC, so you can use "``seek=128``" as well. Having a GPT |
| 169 | on an eMMC device is much more likely than on an SD card, so you should |
| 170 | probably stick to the alternative location, or use one of the boot partitions. |
| 171 | |
| 172 | Installing on an eMMC boot partition from Linux |
| 173 | ``````````````````````````````````````````````` |
| 174 | In the following examples, ``/dev/mmcblkX`` needs to be replaced with the block |
| 175 | device name of the eMMC device. The eMMC device can be recognised by also |
| 176 | listing the boot partitions (``/dev/mmcblkXboot0``) in ``/proc/partitions``. |
| 177 | |
| 178 | To allow booting from one of the eMMC boot partitions, this one needs to be |
| 179 | enabled first. This only needs to be done once, as this setting is |
| 180 | persistent, even though the boot partition can be disabled or changed again |
| 181 | any time later:: |
| 182 | |
| 183 | # apt-get install mmc-utils |
| 184 | # mmc bootbus set single_hs x1 x4 /dev/mmcblkX |
| 185 | # mmc bootpart enable 1 1 /dev/mmcblkX |
| 186 | |
| 187 | The first "1" in the last command points to the boot partition number to be |
| 188 | used, typically devices offer two boot partitions. |
| 189 | |
| 190 | By default Linux disables write access to the boot partitions, to prevent |
| 191 | accidental overwrites. You need to disable the write protection (until the |
| 192 | next reboot), then can write the U-Boot image to the *first* sector of the |
| 193 | selected boot partition:: |
| 194 | |
| 195 | # echo 0 > /sys/block/mmcblkXboot0/force_ro |
| 196 | # dd if=u-boot-sunxi-with-spl.bin of=/dev/mmcblkXboot0 bs=1k |
| 197 | |
| 198 | Installing on an eMMC user data partition from U-Boot |
| 199 | ````````````````````````````````````````````````````` |
| 200 | You can also write the generated image file to an SD card, boot the device |
| 201 | from there, and burn the very same image to the eMMC device from U-Boot. |
| 202 | The following commands copy the image from the SD card to the eMMC device:: |
| 203 | |
| 204 | => mmc dev 0 |
| 205 | => mmc read $kernel_addr_r 0x10 0x7f0 |
| 206 | => mmc dev 1 |
| 207 | => mmc write $kernel_addr_r 0x10 0x7f0 |
| 208 | |
| 209 | You can also copy an image from the 8K offset of an SD card to the 128K |
| 210 | offset of the eMMC (or any combination), just change the "``0x10 0x7f0``" above |
| 211 | to "``0x100 0x700``", respectively. Of course the image file can be loaded via |
| 212 | any other loading method, including ``fatload``, ``ext4load``, ``tftpboot``. |
| 213 | |
| 214 | Installing on an eMMC boot partition from U-Boot |
| 215 | ```````````````````````````````````````````````` |
| 216 | The selected eMMC boot partition needs to be initially enabled first (same |
| 217 | as in Linux above), you can do this from U-Boot with:: |
| 218 | |
| 219 | => mmc dev 1 |
| 220 | => mmc bootbus 1 1 0 0 |
| 221 | => mmc partconf 1 1 1 1 |
| 222 | |
| 223 | The first "1" in both commands denotes the MMC device number. The second "1" |
| 224 | in the partconf command sets the required ``BOOT_ACK`` option, the last two "1"s |
| 225 | selects the active boot partition and the target for the next data access, |
| 226 | respectively. So for the next "``mmc write``" command to address one of the boot |
| 227 | partitions, the last number must either be "1" or "2", "0" would switch (back) |
| 228 | to the normal user data partition. |
| 229 | |
| 230 | Then load the ``u-boot-sunxi-with-spl.bin`` image file into DRAM, either by |
| 231 | reading directly from an SD card or eMMC user data partition, or from a |
| 232 | file system or TFTP (see above), and transfer it to the boot partition:: |
| 233 | |
| 234 | => tftpboot $kernel_addr_r u-boot-sunxi-with-spl.bin |
| 235 | => mmc write $kernel_addr_r 0 0x7f0 |
| 236 | |
| 237 | After that the device should boot from the selected boot partition, which takes |
| 238 | precedence over booting from the user data partition. |
| 239 | |
| 240 | Installing on SPI flash |
| 241 | ^^^^^^^^^^^^^^^^^^^^^^^ |
| 242 | Some devices have a SPI NOR flash chip soldered on the board. If it is |
| 243 | connected to the SPI0 pins on PortC, the BROM can also boot from there. |
| 244 | Typically the SPI flash has the lowest boot priority, so SD card and eMMC |
| 245 | devices will be considered first. |
| 246 | |
| 247 | Installing on SPI flash from Linux |
| 248 | `````````````````````````````````` |
| 249 | If the devicetree enables and describes the SPI flash device, you can access |
| 250 | the SPI flash content from Linux, using the `MTD utils`_:: |
| 251 | |
| 252 | # apt-get install mtd-utils |
| 253 | # mtdinfo |
| 254 | # mtd_debug erase /dev/mtdX 0 0xf0000 |
| 255 | # mtd_debug write /dev/mtdX 0 0xf0000 u-boot-sunxi-with-spl.bin |
| 256 | |
| 257 | ``/dev/mtdX`` needs to be replaced with the respective device name, as listed |
| 258 | in the output of ``mtdinfo``. |
| 259 | |
| 260 | Installing on SPI flash from U-Boot |
| 261 | ``````````````````````````````````` |
| 262 | If SPI flash driver and command support (``CONFIG_CMD_SF``) is enabled in the |
| 263 | U-Boot configuration, the image file can be installed via U-Boot as well:: |
| 264 | |
| 265 | => tftpboot $kernel_addr_r u-boot-sunxi-with-spl.bin |
| 266 | => sf probe |
| 267 | => sf erase 0 +0xf0000 |
| 268 | => sf write $kernel_addr_r 0 $filesize |
| 269 | |
| 270 | Installing on SPI flash via USB in FEL mode |
| 271 | ``````````````````````````````````````````` |
| 272 | If the device is in FEL mode (see below), the SPI flash can also be written to |
| 273 | with the sunxi-fel utility, via an USB(-OTG) cable from any USB host machine:: |
| 274 | |
| 275 | $ sunxi-fel spiflash-write 0 u-boot-sunxi-with-spl.bin |
| 276 | |
| 277 | Booting via the USB(-OTG) FEL mode |
| 278 | ---------------------------------- |
| 279 | If none of the boot locations checked by the BROM contains a medium or valid |
| 280 | signature, the BROM will enter the so-called FEL mode, in which it will |
| 281 | listen to commands from a host on the SoC's USB-OTG interface. Those commands |
| 282 | allow to read from and write to arbitrary memory locations, also to start |
| 283 | execution at any address, which allows to bootstrap a board solely via an |
| 284 | USB cable. Some boards feature a "FEL" or "U-Boot" button, which forces |
| 285 | FEL mode despite a valid boot location being present. The same can be achieved |
| 286 | via a `magic binary`_ on an SD card, which allows to enter FEL mode on any |
| 287 | board. |
| 288 | |
| 289 | To use FEL booting, let the board enter FEL mode, via any of the mentioned |
| 290 | methods (no boot media, FEL button, SD card with FEL binary), then connect |
| 291 | a USB cable to the board's USB OTG port. Some boards (Pine64, TV boxes) don't |
| 292 | have a separate OTG port. In this case mostly one of the USB-A ports is |
| 293 | connected to USB0, and can be used via a non-standard USB-A to USB-A cable. |
| 294 | |
| 295 | Typically there is no on-board indication of FEL mode, other than a new USB |
| 296 | device appearing on the connected host computer. The USB vendor/device ID |
| 297 | is 1f3a:efe8. Mostly this will identify as "sunxi SoC OTG connector in |
| 298 | FEL/flashing mode", but older distributions might still report "Onda |
| 299 | (unverified) V972 tablet in flashing mode". |
| 300 | |
| 301 | The `sunxi_fel`_ tool implements the proprietary BROM protocol, and allows to |
| 302 | bootstrap U-Boot by just providing our venerable u-boot-sunxi-with-spl.bin:: |
| 303 | |
| 304 | $ sudo apt-get install sunxi-tools |
| 305 | $ sunxi-fel uboot u-boot-sunxi-with-spl.bin |
| 306 | |
| 307 | Additional binaries like a kernel, an initial ramdisk or a boot script, can |
| 308 | also be uploaded via FEL, check the Wiki's `FEL page`_ for more details. |
| 309 | |
| 310 | .. _`Arm Trusted Firmware-A`: https://www.trustedfirmware.org/projects/tf-a/ |
| 311 | .. _`docs/plat/allwinner.rst`: https://trustedfirmware-a.readthedocs.io/en/latest/plat/allwinner.html |
| 312 | .. _`crust`: https://github.com/crust-firmware/crust |
| 313 | .. _`configs/`: https://github.com/crust-firmware/crust/tree/master/configs |
| 314 | .. _`crust README`: https://github.com/crust-firmware/crust/blob/master/README.md#building-the-firmware |
| 315 | .. _`linux-sunxi`: https://linux-sunxi.org |
| 316 | .. _`MTD utils`: http://www.linux-mtd.infradead.org/ |
| 317 | .. _`magic binary`: https://github.com/linux-sunxi/sunxi-tools/raw/master/bin/fel-sdboot.sunxi |
| 318 | .. _`sunxi_fel`: https://github.com/linux-sunxi/sunxi-tools |
| 319 | .. _`FEL page`: https://linux-sunxi.org/FEL/USBBoot |