I recently got my Orange Pi Zero 2 shipped and in the previous article, we discussed how to boot official linux images from orangepi.org. In this article, we are going to learn how we can build u-boot image for our Orange Pi Zero 2 board from the mainline source.

Step 1 : Build ATF (Arm Trusted Firmware)

The u-boot build for Orange Pi Zero 2 expects ATF image, so the first thing we need to do is get the ATF image built. For this, pull the ATF source code from GitHub.

code@slashinit

naveen@workstation:~/orangepi$ git clone https://github.com/ARM-software/arm-trusted-firmware.git
Cloning into 'arm-trusted-firmware'...
remote: Enumerating objects: 123350, done.
remote: Counting objects: 100% (8660/8660), done.
remote: Compressing objects: 100% (3259/3259), done.
remote: Total 123350 (delta 5304), reused 8320 (delta 5214), pack-reused 114690
Receiving objects: 100% (123350/123350), 37.24 MiB | 786.00 KiB/s, done.
Resolving deltas: 100% (80795/80795), done.
naveen@workstation:~/orangepi$

Setup the ARCH and CROSS_COMPILE environment variables.

code@slashinit

naveen@workstation:~/orangepi$ export ARCH=arm64
naveen@workstation:~/orangepi$ export CROSS_COMPILE=/opt/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-
naveen@workstation:~/orangepi$

Trigger the build.

code@slashinit

naveen@workstation:~/orangepi/arm-trusted-firmware$ make PLAT=sun50i_h616 DEBUG=1 -j8
Building sun50i_h616
CC lib/libfdt/fdt.c
CC lib/libfdt/fdt_addresses.c
CC lib/libfdt/fdt_empty_tree.c
CC lib/libfdt/fdt_ro.c
CC lib/libfdt/fdt_rw.c
CC lib/libfdt/fdt_strerror.c
CC lib/libfdt/fdt_sw.c
CC lib/libfdt/fdt_wip.c
CC lib/libc/abort.c
CC lib/libc/assert.c
CC lib/libc/exit.c
CC lib/libc/memchr.c
CC lib/libc/memcmp.c
CC lib/libc/memcpy.c
CC lib/libc/memcpy_s.c
CC lib/libc/memmove.c
CC lib/libc/memrchr.c
CC lib/libc/memset.c
CC lib/libc/printf.c
CC lib/libc/putchar.c
CC lib/libc/puts.c
CC lib/libc/snprintf.c
CC lib/libc/strchr.c
CC lib/libc/strcmp.c
CC lib/libc/strlcat.c
CC lib/libc/strlcpy.c
CC lib/libc/strlen.c
CC lib/libc/strncmp.c
CC lib/libc/strnlen.c
CC lib/libc/strrchr.c
CC lib/libc/strtok.c
CC lib/libc/strtoul.c
CC lib/libc/strtoll.c
CC lib/libc/strtoull.c
AS lib/libc/aarch64/setjmp.S
CC lib/libc/strtol.c
AR /home/naveen/orangepi/arm-trusted-firmware/build/sun50i_h616/debug/lib/libfdt.a
CC bl31/bl31_context_mgmt.c
CC bl31/bl31_main.c
CC bl31/bl31_traps.c
CC bl31/interrupt_mgmt.c
CC common/backtrace/backtrace.c
CC common/bl_common.c
CC common/fdt_fixup.c
CC common/runtime_svc.c
CC common/tf_log.c
CC drivers/allwinner/axp/axp805.c
CC drivers/allwinner/axp/common.c
CC drivers/allwinner/sunxi_rsb.c
CC drivers/arm/gic/v2/gicdv2_helpers.c
CC drivers/arm/gic/v2/gicv2_helpers.c
CC drivers/arm/gic/v2/gicv2_main.c
CC drivers/console/multi_console.c
CC drivers/delay_timer/delay_timer.c
CC drivers/delay_timer/generic_delay_timer.c
CC lib/compiler-rt/builtins/popcountdi2.c
CC lib/compiler-rt/builtins/popcountsi2.c
CC lib/cpus/errata_report.c
CC lib/el3_runtime/aarch64/context_mgmt.c
CC lib/el3_runtime/cpu_data_array.c
CC lib/extensions/pmuv3/aarch64/pmuv3.c
CC lib/locks/bakery/bakery_lock_coherent.c
CC lib/psci/psci_common.c
CC lib/psci/psci_main.c
CC lib/psci/psci_mem_protect.c
CC lib/psci/psci_off.c
CC lib/psci/psci_on.c
CC lib/psci/psci_setup.c
CC lib/psci/psci_suspend.c
CC lib/psci/psci_system_off.c
CC lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
CC lib/xlat_tables_v2/xlat_tables_context.c
CC lib/xlat_tables_v2/xlat_tables_core.c
CC lib/xlat_tables_v2/xlat_tables_utils.c
CC plat/allwinner/common/sunxi_bl31_setup.c
CC plat/allwinner/common/sunxi_common.c
CC plat/allwinner/common/sunxi_cpu_ops.c
CC plat/allwinner/common/sunxi_native_pm.c
CC plat/allwinner/common/sunxi_pm.c
CC plat/allwinner/common/sunxi_prepare_dtb.c
CC plat/allwinner/common/sunxi_security.c
CC plat/allwinner/common/sunxi_topology.c
CC plat/allwinner/sun50i_h616/sunxi_idle_states.c
CC plat/allwinner/sun50i_h616/sunxi_power.c
CC plat/common/aarch64/plat_common.c
CC plat/common/plat_bl_common.c
CC plat/common/plat_gicv2.c
CC plat/common/plat_log_common.c
CC plat/common/plat_psci_common.c
CC services/arm_arch_svc/arm_arch_svc_setup.c
CC services/std_svc/std_svc_setup.c
AS bl31/aarch64/bl31_entrypoint.S
AS bl31/aarch64/crash_reporting.S
AS bl31/aarch64/ea_delegate.S
AS bl31/aarch64/runtime_exceptions.S
AS common/aarch64/debug.S
AS lib/aarch64/cache_helpers.S
AS drivers/ti/uart/aarch64/16550_console.S
AS lib/cpus/aarch64/cortex_a53.S
AS lib/aarch64/misc_helpers.S
AS lib/cpus/aarch64/cpu_helpers.S
AS lib/cpus/aarch64/dsu_helpers.S
AS lib/cpus/aarch64/wa_cve_2017_5715_bpiall.S
AS lib/cpus/aarch64/wa_cve_2017_5715_mmu.S
AS lib/el3_runtime/aarch64/context.S
AS lib/el3_runtime/aarch64/cpu_data.S
AS lib/locks/exclusive/aarch64/spinlock.S
AS lib/psci/aarch64/psci_helpers.S
AS lib/psci/aarch64/runtime_errata.S
AS lib/xlat_tables_v2/aarch64/enable_mmu.S
AS plat/allwinner/common/plat_helpers.S
AS plat/common/aarch64/platform_helpers.S
AS plat/common/aarch64/platform_mp_stack.S
PP bl31/bl31.ld.S
AR /home/naveen/orangepi/arm-trusted-firmware/build/sun50i_h616/debug/lib/libc.a
LD /home/naveen/orangepi/arm-trusted-firmware/build/sun50i_h616/debug/bl31/bl31.elf
BIN /home/naveen/orangepi/arm-trusted-firmware/build/sun50i_h616/debug/bl31.bin
OD /home/naveen/orangepi/arm-trusted-firmware/build/sun50i_h616/debug/bl31/bl31.dump

Built /home/naveen/orangepi/arm-trusted-firmware/build/sun50i_h616/debug/bl31.bin successfully
naveen@workstation:~/orangepi/arm-trusted-firmware$

The bin file called bl31.bin that we got above is our ATF image, that we can pass to u-boot during building in the next step.

Step 2 : Build u-boot

The first step is to clone the u-boot source code.

code@slashinit

naveen@workstation:~/orangepi/arm-trusted-firmware$ cd ../
naveen@workstation:~/orangepi$ git clone https://github.com/u-boot/u-boot.git
Cloning into 'u-boot'...
remote: Enumerating objects: 943449, done.
remote: Counting objects: 100% (3682/3682), done.
remote: Compressing objects: 100% (1396/1396), done.
remote: Total 943449 (delta 2348), reused 3348 (delta 2268), pack-reused 939767
Receiving objects: 100% (943449/943449), 250.68 MiB | 749.00 KiB/s, done.
Resolving deltas: 100% (767634/767634), done.
Updating files: 100% (20293/20293), done.
naveen@workstation:~/orangepi$

Setup the enviroment variables.

code@slashinit

naveen@workstation:~/orangepi$ export ARCH=arm64
naveen@workstation:~/orangepi$ export CROSS_COMPILE=/opt/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-
naveen@workstation:~/orangepi$

Configure the u-boot.

code@slashinit

naveen@workstation:~/orangepi$ cd u-boot/
naveen@workstation:~/orangepi/u-boot$ ls configs | grep orangepi_zero
orangepi_zero2_defconfig
orangepi_zero_defconfig
orangepi_zero_plus2_defconfig
orangepi_zero_plus2_h3_defconfig
orangepi_zero_plus_defconfig
naveen@workstation:~/orangepi/u-boot$ make orangepi_zero2_defconfig -j8
HOSTCC scripts/basic/fixdep
HOSTCC scripts/kconfig/conf.o
YACC scripts/kconfig/zconf.tab.c
LEX scripts/kconfig/zconf.lex.c
HOSTCC scripts/kconfig/zconf.tab.o
HOSTLD scripts/kconfig/conf
#
# configuration written to .config
#
naveen@workstation:~/orangepi/u-boot$

Trigger the build. Note that we pass the ATF image that we built in previous step.

code@slashinit

naveen@workstation:~/orangepi/u-boot$ make BL31=/home/naveen/orangepi/arm-trusted-firmware/build/sun50i_h616/debug/bl31.bin -j24
UPD include/generated/timestamp_autogenerated.h
HOSTCC scripts/basic/fixdep
HOSTCC scripts/dtc/flattree.o
HOSTCC scripts/dtc/dtc.o
HOSTCC scripts/dtc/fstree.o
HOSTCC scripts/dtc/data.o
HOSTCC scripts/dtc/livetree.o
HOSTCC scripts/dtc/treesource.o
HOSTCC scripts/dtc/srcpos.o
HOSTCC scripts/dtc/checks.o
HOSTCC scripts/dtc/util.o
YACC scripts/dtc/dtc-parser.tab.h
LEX scripts/dtc/dtc-lexer.lex.c
YACC scripts/dtc/dtc-parser.tab.c
CFG u-boot.cfg
PYMOD rebuild
CC lib/asm-offsets.s
CC arch/arm/lib/asm-offsets.s
...
...
...
CC spl/lib/date.o
CC spl/lib/rtc-lib.o
AR spl/drivers/i2c/built-in.o
CC spl/lib/elf.o
AR spl/drivers/serial/built-in.o
AR spl/boot/built-in.o
OBJCOPY u-boot.srec
OBJCOPY u-boot-nodtb.bin
SYM u-boot.sym
AR spl/drivers/mmc/built-in.o
AR spl/drivers/built-in.o
RELOC u-boot-nodtb.bin
DTC arch/arm/dts/sun50i-h616-orangepi-zero2.dtb
DTC arch/arm/dts/sun50i-h616-x96-mate.dtb
SHIPPED dts/dt.dtb
CAT u-boot-dtb.bin
MKIMAGE u-boot.img
COPY u-boot.dtb
MKIMAGE u-boot-dtb.img
AR spl/lib/built-in.o
COPY u-boot.bin
LD spl/u-boot-spl
SYM spl/u-boot-spl.sym
OBJCOPY spl/u-boot-spl-nodtb.bin
COPY spl/u-boot-spl.bin
MKIMAGE spl/sunxi-spl.bin
BINMAN .binman_stamp
OFCHK .config
naveen@workstation:~/orangepi/u-boot$

We can find the u-boot bin files in the current folder.

Conclusion

This post talked about how you can compile u-boot from mainline source code, for Orange Pi Zero 2 board. The next post talks about how we can boot u-boot image on Orange Pi Zero 2 using USB boot mode.