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.symAnd 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.outYou 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.logUsing 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.
u-boot/tools/binman/README.rstAs 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.cThose 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
./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 appendThen 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/nullThis looks identical to the last, except for the filename in the -d option.
./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))
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 matchesThis leads us to a common file:
u-boot/arch/arm/dts/sunxi-u-boot.dtsiAnd a hidden file:
.sun50i-h5-orangepi-pc2.dtb.dts.tmpThis 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.
Tom's electronics pages / tom@mmto.org