January 27, 2026

Allwinner H5 chip - the U-boot Makefile, part 1

The previous page told how to turn the file u-boot-sunxi-with-spl.bin into a bootable SD card that will allow the U-boot "saveenv" command to work.

The goal here is not a comprehensive study of the U-boot Makefile, but a study of the "end game" that produces u-boot-sunxi-with-spl.bin

First of all I use what is now my favorite command "ls -lrt" to get a summary of all the products of a U-boot build.

cd u-boot/spl ; ls -lrt
-rw-r--r--  1 tom tom  32768 Jan 27 11:42 sunxi-spl.bin
-rwxr-xr-x  1 tom tom 780080 Jan 27 11:42 u-boot-spl
-rwxr-xr-x  1 tom tom  30920 Jan 27 11:42 u-boot-spl.bin
-rw-r--r--  1 tom tom   1051 Jan 27 11:42 u-boot-spl.lds
-rw-r--r--  1 tom tom 249092 Jan 27 11:42 u-boot-spl.map
-rwxr-xr-x  1 tom tom  30920 Jan 27 11:42 u-boot-spl-nodtb.bin
-rw-r--r--  1 tom tom  24619 Jan 27 11:42 u-boot-spl.sym
And we have the main show:
cd u-boot ; ls -lrt
-rw-r--r--   1 tom tom    1509 Jan 27 11:42 u-boot.lds
-rwxr-xr-x   1 tom tom 6694920 Jan 27 11:42 u-boot
-rw-r--r--   1 tom tom 1084366 Jan 27 11:42 u-boot.map
-rwxr-xr-x   1 tom tom 2216836 Jan 27 11:42 u-boot.srec
-rwxr-xr-x   1 tom tom  865176 Jan 27 11:42 u-boot-nodtb.bin
drwxr-xr-x   3 tom tom    4096 Jan 27 11:42 dts
-rw-r--r--   1 tom tom  900808 Jan 27 11:42 u-boot-dtb.bin
-rw-r--r--   1 tom tom  900808 Jan 27 11:42 u-boot.bin
-rw-r--r--   1 tom tom  264238 Jan 27 11:42 u-boot.sym
-rw-r--r--   1 tom tom  128041 Jan 27 11:42 System.map
drwxr-xr-x  14 tom tom    4096 Jan 27 11:42 spl
-rw-r--r--   1 tom tom  901820 Jan 27 11:42 u-boot.img
-rw-r--r--   1 tom tom   35632 Jan 27 11:42 u-boot.dtb
-rw-r--r--   1 tom tom  901820 Jan 27 11:42 u-boot-dtb.img
-rw-r--r--   1 tom tom 1452589 Jan 27 11:42 u-boot-sunxi-with-spl.fit.itb
-rw-r--r--   1 tom tom 1453613 Jan 27 11:42 u-boot-sunxi-with-spl.fit.fit
-rw-r--r--   1 tom tom 1486381 Jan 27 11:42 u-boot-sunxi-with-spl.bin
-rw-r--r--   1 tom tom     393 Jan 27 11:42 u-boot-sunxi-with-spl.map
-rw-r--r--   1 tom tom   32032 Jan 27 11:42 u-boot.dtb.out
You should be asking, "what the heck is all this stuff?". A reasonable thing to do is to study the Makefile, but it is a 2804 line monster. A more reasonable thing is to build using the following command:
make V=1 >ubuildv1.log
Using the V=1 switch will exactly show all the commands run with the command line arguments passed to them. Here is the log, should you care to preuse it:

Having done this, I figured it would be a reasonable thing to search this log for "u-boot-sunxi-with-spl", however this string does not appear at all in the build log! Nothing is ever simple or straightforward. Some lines in the log are extremely long and get wrapped multiple times. I find it beneficial to edit the log and insert blank lines to make it clear where this happens.

mkimage and binman

These are both tools that come along with U-boot. They both get involved in the process of generating the firmware image we are interested in. I get the impression that mkimage has been around for a while, but "binman" is a newer fancier thing. Binman is written entirely in python! 16727 lines of python by my count.
For documentation on binman, see:
u-boot/tools/binman/README.rst
As for mkimage, my Fedora distribution has this in the /bin directory and it identifies itself as "mkimage version 2022.10-dirty". No man page. You will read a lot about FIT files (flattened image tree). The mkimage program is written in C and gets built as part of the U-boot build process.

You can find source for a man page at u-boot/doc/mkimage.1
You can render this via "man ./mkimage.1"

The source for mkimage is in u-boot/tools and is only 1001 lines of C, but it is really just the front end for a bunch of helper programs like:

** mksunxiboot.c
   sunxi_egon.c
** sunxi-spl-image-builder.c
   sunxi_toc0.c
Those prefixed with "**" compile to their own standalone program, but I don't see either of them getting used in my build log.

The U-boot build uses its own versions of mkimage and binman, invoking them as:

./tools/mkimage
./tools/binman/binman

How does mkimage actually get used?

Enough of this high level view, let's see how mkimage actually gets used according to the build log. I see 3 places where mkimage is used.
./tools/mkimage -A arm -T "sunxi_egon" -a 0x10060 -n "sun50i-h5-orangepi-pc2"
    -d spl/u-boot-spl.bin spl/sunxi-spl.bin
	>/dev/null  && cat /dev/null

-A is the architecture
-T is the image type
-a is the load address
-n is the "primary configuration"
-d is the image data file (input)

For sunxi_egon, the primary configuration is the name to use for the device tree.
What is sunxi-egon? eGON is the magic number "signature" that the bootrom looks for to identify a thing to be loaded.

./tools/mkimage -f auto -A arm -T firmware -C none -O u-boot -a 0x4a000000 -e 0x4a000000
  -p 0x0 -n "U-Boot 2025.10trebisky-dirty for sunxi board" -E
  -b arch/arm/dts/sun50i-h5-orangepi-pc2.dtb  -d u-boot-nodtb.bin u-boot.img
  >/dev/null  && cat /dev/null

-f is the image tree source file (I always cringe when I see "auto")
-C is compression (none, thankfully)
-O is the operating system
-e is the entry point address
-p is the external position for data
-E says to store data external to the fit
-b is the device tree binary to append
Then finally:
./tools/mkimage -f auto -A arm -T firmware -C none -O u-boot -a 0x4a000000 -e 0x4a000000
  -p 0x0 -n "U-Boot 2025.10trebisky-dirty for sunxi board" -E
  -b arch/arm/dts/sun50i-h5-orangepi-pc2.dtb  -d u-boot-nodtb.bin u-boot-dtb.img
  >/dev/null  && cat /dev/null
This looks identical to the last, except for the filename in the -d option.

And what about binman?

This is the last line in the build log (other than the "check-of.sh script)
./tools/binman/binman   --toolpath ./tools  build -u -d ./u-boot.dtb -O .
  -m --allow-missing --fake-ext-blobs  -I . -I . -I ./board/sunxi
  -I arch/arm/dts -a of-list="sun50i-h5-orangepi-pc2"
  -a atf-bl1-path= -a atf-bl31-path=/Projects/ARM-sources/h5/bl31.elf
  -a tee-os-path= -a ti-dm-path= -a opensbi-path= -a default-dt="sun50i-h5-orangepi-pc2"
  -a scp-path=/dev/null -a rockchip-tpl-path= -a spl-bss-pad= -a tpl-bss-pad=1
  -a vpl-bss-pad=1 -a spl-dtb= -a tpl-dtb= -a vpl-dtb= -a pre-load-key-path= -a of-spl-remove-props=
The line in the Makefile that produces all of this is:
cmd_binman = $(srctree)/tools/binman/binman $(if $(BINMAN_DEBUG),-D) \
        $(foreach f,$(BINMAN_TOOLPATHS),--toolpath $(f)) \
                --toolpath $(objtree)/tools \
        $(if $(BINMAN_VERBOSE),-v$(BINMAN_VERBOSE)) \
        build -u -d $(binman_dtb) -O . -m \
        --allow-missing --fake-ext-blobs \
        $(if $(BINMAN_ALLOW_MISSING),--ignore-missing) \
        -I . -I $(srctree) -I $(srctree)/board/$(BOARDDIR) \
        $(foreach f,$(of_list_dirs),-I $(f)) -a of-list=$(of_list) \
        $(foreach f,$(BINMAN_INDIRS),-I $(f)) \
        -a atf-bl1-path=${BL1} \
        -a atf-bl31-path=${BL31} \
        -a tee-os-path=${TEE} \
        -a ti-dm-path=${TI_DM} \
        -a opensbi-path=${OPENSBI} \
        -a default-dt=$(default_dt) \
        -a scp-path=$(SCP) \
        -a rockchip-tpl-path=$(ROCKCHIP_TPL) \
        -a spl-bss-pad=$(if $(CONFIG_SPL_SEPARATE_BSS),,1) \
        -a tpl-bss-pad=$(if $(CONFIG_TPL_SEPARATE_BSS),,1) \
        -a vpl-bss-pad=$(if $(CONFIG_VPL_SEPARATE_BSS),,1) \
        -a spl-dtb=$(CONFIG_SPL_OF_REAL) \
        -a tpl-dtb=$(CONFIG_TPL_OF_REAL) \
        -a vpl-dtb=$(CONFIG_VPL_OF_REAL) \
        -a pre-load-key-path=${PRE_LOAD_KEY_PATH} \
        -a of-spl-remove-props=$(CONFIG_OF_SPL_REMOVE_PROPS) \
        $(BINMAN_$(@F))

The mystery of "u-boot-sunxi-with-spl"

The mystery is why this string does not show up in the build log. I do a recursive grep on this string and turn up a number of things.

For interesting places where this string is mentioned, look at:

board/sunxi/README.sunxi64
doc/board/allwinner/sunxi.rst
tools/binman/binman.rst

Consider the string "sun50i-h5-orangepi-pc2" that pops up in various mkimage lines above. This is the name of the device tree:

arch/arm/dts/sun50i-h5-orangepi-pc2.dtb: binary file matches
This leads us to a common file:
u-boot/arch/arm/dts/sunxi-u-boot.dtsi
And a hidden file:
.sun50i-h5-orangepi-pc2.dtb.dts.tmp
This has a section that begins like this:
# 29 "arch/arm/dts/sunxi-u-boot.dtsi"
&binman {
 u-boot-sunxi-with-spl {
  filename = "u-boot-sunxi-with-spl.bin";
  pad-byte = <0xff>;
To make a long story short, the file arch/arm/dts/sunxi-u-boot.dtsi is 129 lines long and the bulk of it is the "binman" section that controls the process binman uses to generate u-boot-sunxi-with-spl.bin.
It even includes this filename, which seems to appear nowhere else!

Conclusion

All of this is interesting, and should I desire to dive deeper, I have a variety of starting points now. At this point though, this spells the end of this rabbit hole. At least for the time being.


Have any comments? Questions? Drop me a line!

Tom's electronics pages / tom@mmto.org