U-Boot
This page describes how to build and use upstream U-Boot for 32bit (armv7/armhf) sunxi devices.
Differences for ARM64 are only mentioned in the Compile U-Boot section. For more info see directly board/sunxi/README.sunxi64 in uboot sources.
We have a separate page for the deprecated legacy sunxi branch of U-Boot.
Status Matrix
SoC | Basic support | SD-Card/eMMC boot | USB | Ethernet boot | HDMI display | LCD display |
---|---|---|---|---|---|---|
F1C-100s | v2022.04 | v2022.07 | v2023.10 | N/A | N/A | Unknown |
A10 | v2014.10 | v2014.10 | v2014.10 | v2014.10 | v2015.01 | v2015.04 |
A10s | v2014.10 | v2014.10 | v2014.10 | v2014.10 | v2015.01 | v2015.04 |
A13 | v2014.10 | v2014.10 | v2014.10 | v2014.10 | N/A | v2015.04 |
A20 | v2014.07 | v2014.07 | v2014.10 | v2014.07 | v2015.01 | v2015.04 |
A23 | v2015.01 | v2015.04 | v2015.04 | N/A | N/A | v2015.04 |
A31 | v2015.01 | v2015.01 | v2015.01 | v2015.01 | v2015.01 | v2015.04 |
A33 | v2015.07 | v2015.07 | v2015.07 | N/A | N/A | v2015.07 |
A64 | v2016.05 | v2016.05 | v2016.11 | v2016.09 | v2017.07 | v2017.07 |
A80 | v2015.07 | v2015.07 | TODO | TODO | TODO | TODO |
A83T | v2016.01 | v2016.01 | v2016.01 | v2016.01 | TODO | TODO |
H3 | v2016.01 | v2016.01 | v2016.03 | v2016.09 | v2017.07 | N/A |
H5 | v2017.05 | v2017.05 | v2017.05 | v2017.05 | v2017.07 | N/A |
H6 | v2018.09 | v2018.09 | v2019.10 | v2020.07 | TODO | TODO |
R40 | v2017.05 | v2017.05 | v2020.04 | v2020.04 | TODO | TODO |
V3 / V3s / S3L | v2017.05 | v2017.05 | v2017.05 | Unknown | TODO | TODO |
H616 | v2021.04 | v2021.04 | v2023.10 | v2021.04 | TODO | TODO |
T113-s3 | v2024.01 | v2024.01 | v2024.01 | Unknown | N/A | TODO |
D1 | Unknown | Unknown | Unknown | Unknown | TODO | TODO |
D1s | Unknown | Unknown | Unknown | Unknown | N/A | TODO |
Device support
To know if your device is supported in U-Boot, check out the respective device page.
Here is the list of all devices supporting mainline U-Boot.
Changelog (outdated)
A sunxi specific changelog for upstream is available here. It has only been kept up to date until 2019.
Compile U-Boot
Get a toolchain
Our toolchain page explains everything you need to know about installing a toolchain.
Get swig
Install the swig compiler.
apt-get install swig
Get python3-dev
If you experience:
fatal error: Python.h: No such file or directory
Then install the development package for python-3:
apt-get install python3-dev
Get dtc
The device tree compiler, dtc, needs to be available to successfully build u-boot.
apt-get install device-tree-compiler
Get Trusted Firmware-A (aarch64)
If you are building U-Boot for an arm64/aarch64 device, you need to include Trusted Firmware-A (TF-A, formerly known as ATF).
You can get this from:
git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git
To build this, run:
make CROSS_COMPILE=aarch64-linux-gnu- PLAT=<platform> DEBUG=1 bl31
Change <platform> to your needs. sun50i_a64 for example is suitable for H5 and A64 devices.
See docs/plat/allwinner.rst in the TF-A source or doc/board/allwinner/sunxi.rst in the U-Boot source for more information.
Clone the repository
You can clone the u-boot repository by running:
git clone git://git.denx.de/u-boot.git
You might want to use the latest release instead of the newest development code. To get a list of available releases, which are tags, run:
git tag -l
Check out your preferred release:
git checkout v2024.01
Determine build target
Every device page should list the device specific u-boot config under the section Mainline U-Boot.
This config usually follows the <device>_defconfig schema. For instance, if your device is the Cubieboard2 then your build target is Cubieboard2_defconfig.
You should be able to find this file in the u-boot tree under configs/
Build
The commands below include a menuconfig step, this allows you to change some build-time settings, but can normally be skipped.
When the build has completed, there will be u-boot-sunxi-with-spl.bin available at the top level of your u-boot repository. Follow the u-boot installation step of the respective howto you are following for your preferred installation medium.
armhf
make CROSS_COMPILE=arm-linux-gnueabihf- <board_name>_defconfig make CROSS_COMPILE=arm-linux-gnueabihf- menuconfig make CROSS_COMPILE=arm-linux-gnueabihf-
arm64
make CROSS_COMPILE=aarch64-linux-gnu- BL31=<path_to_arm-trusted-firmware>/build/sun50i_a64/debug/bl31.bin <board_name>_defconfig make CROSS_COMPILE=aarch64-linux-gnu- BL31=<path_to_arm-trusted-firmware>/build/sun50i_a64/debug/bl31.bin menuconfig make CROSS_COMPILE=aarch64-linux-gnu- BL31=<path_to_arm-trusted-firmware>/build/sun50i_a64/debug/bl31.bin
Configure U-Boot
This article provides a collection of various scenarios for booting with U-Boot.
Boot
For getting these bits loaded onto the hardware, please refer to the respective howto:
Booting with boot.cmd
For booting from SD with mainline U-Boot, the recommended way is:
- create a file boot.cmd on the first partition (also check Kernel arguments for extra 'bootargs' options):
mainline kernel | sunxi-3.4 kernel |
---|---|
setenv bootargs console=ttyS0,115200 root=/dev/mmcblk0p2 rootwait panic=10 load mmc 0:1 0x43000000 ${fdtfile} || load mmc 0:1 0x43000000 boot/${fdtfile} load mmc 0:1 0x42000000 uImage || load mmc 0:1 0x42000000 boot/uImage bootm 0x42000000 - 0x43000000 |
setenv bootm_boot_mode sec setenv bootargs console=ttyS0,115200 root=/dev/mmcblk0p2 rootwait panic=10 load mmc 0:1 0x43000000 script.bin || load mmc 0:1 0x43000000 boot/script.bin load mmc 0:1 0x42000000 uImage || load mmc 0:1 0x42000000 boot/uImage bootm 0x42000000 |
- If you also want to use an initramfs, please refer to the Initial Ramdisk article for details.
- If you're wondering why setting bootm_boot_mode might be necessary for older kernels, have a look at the details of PSCI.
- Note: Directly using a zImage is also supported by U-Boot for the sunxi platform. Substitute zImage in place of uImage in the commands above, and then use the bootz command instead of bootm.
- Note: In order to boot your newly created arm64 or riscv kernel, remember to use Image instead of uImage/zImage. You also have to load it with booti instead of bootm/bootz. So you have to adopt the corresponding lines in the boot.cmd file.
- boot.cmd isn't used directly, but needs to be wrapped with uboot header with the command:
mkimage -C none -A arm -T script -d boot.cmd boot.scr
Booting with extlinux.conf
Mainline U-Boot also use syslinux/extlinux as payload.
You need to install the boot configuration file extlinux.conf in an ext2/3/4 partition of SD card and U-Boot will find and execute it. This is conceptually identical to creating a GRUB configuration file on a desktop PC.
Example extlinux.conf:
TIMEOUT 100 DEFAULT default MENU TITLE Boot menu LABEL default MENU LABEL Default LINUX /zImage FDT /sun4i-a10-marsboard.dtb APPEND root=/dev/sda1 rootwait console=tty0 console=ttyS0,115200n8 LABEL exit MENU LABEL Local boot script (boot.scr) LOCALBOOT 1
Setting u-boot environment variables
There is a difference in setting environment variables between the boot script and the U-Boot shell.
Inside the shell you would set, for instance:
setenv root /dev/sda1
But in the script you would use:
root=/dev/sda1
NAND
Example U-Boot environment, as found in uEnv.txt
from a stock android U-Boot environment partition
bootdelay=0 bootcmd=run setargs boot_normal console=ttyS0,115200 nand_root=/dev/nandc mmc_root=/dev/mmcblk0p4 init=/init loglevel=8 setargs=setenv bootargs console=${console} root=${nand_root} init=${init} loglevel=${loglevel} boot_normal=nand read 40007800 boot;boota 40007800 boot_recovery=nand read 40007800 recovery;boota 40007800 boot_fastboot=fastboot
NFS
Recent version of U-Boot are able to boot from NFS as well as TFTP, but you have to get rid of the automatic setup of FTP. Check Ethernet for more information.
Note: on the A20 based cubieboards, this only seems to work on the stable kernel, not on stage.
FB console
To get U-Boot output shown on the built-in framebuffer driver (currently, HDMI only at 1024x768), add the following to your boot.cmd:
setenv stdout=serial,vga setenv stderr=serial,vga
The default environment has these values set as well.
LCD Settings
There is a separate wiki page about configuring LCD in U-Boot.
Install U-Boot
- Convert the boot.cmd to boot.scr using mkimage:
armhf
mkimage -C none -A arm -T script -d boot.cmd boot.scr
arm64
mkimage -C none -A arm64 -T script -d boot.cmd boot.scr
- Copy the bootloader to the installation media
dd if=u-boot-sunxi-with-spl.bin of=/dev/sdX bs=1024 seek=8
- copy kernel files to the first partition
- For a 3.4 kernel you need uImage (linux kernel) and script.bin (binary representation of FEX).
- For a device tree based kernel ("mainline", 4.x) you need the kernel image (uImage, zImage or Image) and the device-specific .dtb file (the one referenced in the ${fdtfile} above) that is generated as part of your kernel compilation.
Look at Manual build howto for more details.
Troubleshooting
USB 1.x, USB keyboards (U-Boot < v2015.07)
U-Boot v2015.07 and later shouldn't have problems supporting mixed USB 1.x/2.0 devices. OHCI and EHCI no longer conflict with each other (after the switch to device model).
Previous U-Boot versions (v2015.04 and older) have a problem supporting both USB 1.x (OHCI) and USB 2.0 (EHCI) at the same time - the latter includes the SUNXI_EHCI driver for Allwinner boards.
- Unfortunately, this also affects many USB HID / keyboard devices which would not be detected properly by U-Boot. The typical message in this case is "cannot reset port N!?", where N is whichever USB port those devices were attached to.
A possible workaround is to place an external USB 2.0 hub between your board and these USB devices.
See: http://lists.denx.de/pipermail/u-boot/2015-January/200162.html.
U-Boot 2015.07+ won't start
If you're using a recent (device model based) U-Boot, and the SPL just hangs after initializing the DRAM (CPU: 912000000Hz, AXI/AHB/APB: 3/2/2
or something similar), chances are that your main U-Boot binary may be missing DTB information / a proper device tree. Depending on the (possibly outdated) instructions you followed: double-check that you're not incorrectly using u-boot.bin instead of u-boot-dtb.bin, or u-boot.img instead of u-boot-dtb.img.
Legacy kernel won't start
- If your 3.4.x kernel refuses to boot / gets stuck right after "Starting kernel ...":
- Double-check that bootm_boot_mode is set to "sec"! (see above)
- For U-Boot 2018.09-rc1 or later, set CONFIG_ARMV7_LPAE=n in .config or apply https://patchwork.ozlabs.org/patch/1058338/
- If you don't have a serial console and only use VGA/HDMI/LCD, then it might be also the case of "Unrecognized/unsupported machine ID" (see below).
Unrecognized/unsupported machine ID
The sunxi-3.4 kernel may fail to boot with one of the following error messages on the serial console (but this message is not visible on a HDMI monitor or a LCD display!):
Error: unrecognized/unsupported machine ID (r1 = 0x10001008). Error: unrecognized/unsupported machine ID (r1 = 0x1000102a). Error: unrecognized/unsupported machine ID (r1 = 0x100010bb).
In this case either upgrade to a recent stage/sunxi-3.4 kernel (github branch) - or try to "Enable workarounds for booting old kernels" in U-Boot:
make menuconfig
ormake CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
, the option is located under "ARM architecture". (Make sure to rebuild your U-Boot after changing it.)
If upgrading to stage/sunxi-3.4 is not an option (i.e. using some old and very much diverged sunxi-3.4 fork is really necessary), then the following patches can be cherry-picked (= selectively merged as a set):
wget https://github.com/linux-sunxi/linux-sunxi/commit/5052b83aa44dc16d6662d8d9d936166c139ad8c5.patch wget https://github.com/linux-sunxi/linux-sunxi/commit/9a1cd034181af628d4145202289e1993c1687db6.patch wget https://github.com/linux-sunxi/linux-sunxi/commit/c4c4664ed1a2f35e54a33ae4e65f517721ff43b5.patch wget https://github.com/linux-sunxi/linux-sunxi/commit/ade08aa6e5249a9e75a97393e86c250b2bcb3ec8.patch wget https://github.com/linux-sunxi/linux-sunxi/commit/16b25a95327f45a995f6efcf3e9d83a414231af9.patch wget https://github.com/linux-sunxi/linux-sunxi/commit/dea62f21deb177053b84b15a519dff6c74d061d9.patch wget https://github.com/linux-sunxi/linux-sunxi/commit/d47d367036be38c5180632ec8a3ad169a4593a88.patch git am 5052b83aa44dc16d6662d8d9d936166c139ad8c5.patch git am 9a1cd034181af628d4145202289e1993c1687db6.patch git am c4c4664ed1a2f35e54a33ae4e65f517721ff43b5.patch git am ade08aa6e5249a9e75a97393e86c250b2bcb3ec8.patch git am 16b25a95327f45a995f6efcf3e9d83a414231af9.patch git am dea62f21deb177053b84b15a519dff6c74d061d9.patch git am d47d367036be38c5180632ec8a3ad169a4593a88.patch
It is required to apply all of them, as they contain important stability/safety changes. The last patch in this series only takes care of the safety guard, which exists there specifically to block booting problematic kernels. Just removing the safety guard alone without applying all the bugfixes will lead to obscure runtime problems, please don't be tempted to do this.
ImportError: No module named _libfdt
If you see the following error when compiling on Arch Linux arm
ImportError: No module named _libfdt
install dtc
sudo pacman -S dtc
Adding a new device to upstream U-Boot
http://lists.denx.de/pipermail/u-boot/2014-December/199351.html
DRAM Settings
Failsafe DRAM settings, based on standard JEDEC timings
Each device has DRAM settings configured in its defconfig file in the U-Boot "configs" directory (here is an example for the Cubietruck board). The slow failsafe DRAM settings for an A10/A13/A20 device may look like:
+S:CONFIG_DRAM_CLK=360 +S:CONFIG_DRAM_ZQ=123 +S:CONFIG_DRAM_EMR1=4 +S:CONFIG_DRAM_TIMINGS_DDR3_800E_1066G_1333J=y
A more complete set of available Kconfig options and their descriptions can be found here: http://git.denx.de/?p=u-boot.git;a=blob;f=board/sunxi/Kconfig;h=e1d4ab148f0838d746889775cfbab5bed57838bf;hb=a705ebc81b7f91bbd0ef7c634284208342901149#l177
The settings from the Android firmware
Somewhat better settings can be retrieved by the meminfo tool from the stock Android or GNU/Linux system, provided by the device manufacturer. It still makes sense to test the reliability of the resulting DRAM configuration. Because some vendors are providing poor configuration for ZQ or EMR1, but nevertheless trying to optimistically set the DRAM clock speed too high.
Performance optimized DRAM settings
Tuning DRAM setting for each individual board can provide much better performance than the failsafe defaults. This involves trial and error testing of different settings using a tool until an optimal combination is found. The DRAM Controller page provides links to start researching this topic. This approach will be time consuming, so a satisfactory solution using one of the other approaches may be best to start with.