After a standard u-boot build:
$ export CROSS_COMPILE=riscv64-linux-gnu-
$ export OPENSBI=/usr/share/qemu/opensbi-riscv64-generic-fw_dynamic.bin
$ make sifive_unleashed_defconfig
$ make all
We collect some of the outputs into a directory:
our-directory <- u-boot/spl/u-boot-spl.bin
our-directory <- u-boot/u-boot-nodtb.bin
our-directory <- u-boot/arch/riscv/dts/hifive-unleashed-a00.dtb
We also fetch opensbi fw_dynamic (into the same directory):
our-directory <- /usr/share/qemu/opensbi-riscv64-generic-fw_dynamic.bin
Lets pause for a second. What do we know about the generated .itb file (which we did not fetch)?
$ dumpimage -l u-boot.itb
FIT description: Configuration to load OpenSBI before U-Boot
Created: Thu Nov 27 03:03:59 2025
Image 0 (uboot)
Description: U-Boot
Created: Thu Nov 27 03:03:59 2025
Type: Standalone Program
Compression: uncompressed
Data Size: 583224 Bytes = 569.55 KiB = 0.56 MiB
Architecture: RISC-V
Load Address: 0x80200000
Entry Point: unavailable
Image 1 (opensbi)
Description: OpenSBI fw_dynamic Firmware
Created: Thu Nov 27 03:03:59 2025
Type: Firmware
Compression: uncompressed
Data Size: 115328 Bytes = 112.62 KiB = 0.11 MiB
Architecture: RISC-V
OS: RISC-V OpenSBI
Load Address: 0x80000000
Image 2 (fdt-1)
Description: hifive-unleashed-a00
Created: Thu Nov 27 03:03:59 2025
Type: Flat Device Tree
Compression: uncompressed
Data Size: 19464 Bytes = 19.01 KiB = 0.02 MiB
Architecture: Unknown Architecture
Default Configuration: 'conf-1'
Configuration 0 (conf-1)
Description: hifive-unleashed-a00
Kernel: unavailable
Firmware: opensbi
FDT: fdt-1
Loadables: uboot
Neat! Okay, lets make the same thing as a starting point for future work.
$ cd /our-directory
$ nano u-boot.its
/dts-v1/;
/ {
description = "Configuration to load OpenSBI before U-Boot";
#address-cells = <2>;
images {
uboot {
description = "U-Boot";
type = "standalone";
arch = "riscv";
compression = "none";
load = <0x80200000>;
data = /incbin/("u-boot-nodtb.bin");
};
opensbi {
description = "OpenSBI fw_dynamic Firmware";
type = "firmware";
arch = "riscv";
os = "opensbi";
compression = "none";
load = <0x80000000>;
entry = <0x80000000>;
data = /incbin/("opensbi-riscv64-generic-fw_dynamic.bin");
};
fdt-1 {
description = "hifive-unleashed-a00";
type = "flat_dt";
compression = "none";
data = /incbin/("hifive-unleashed-a00.dtb");
};
};
configurations {
default = "conf-1";
conf-1 {
description = "hifive-unleashed-a00";
firmware = "opensbi";
fdt = "fdt-1";
loadables = "uboot";
};
};
};
That should do it. Lets generate a .itb from our .its file:
$ mkimage u-boot.its u-boot.itb
# hmm. or, maybe...
$ mkimage -E -B 0x8 -f u-boot.its u-boot.itb
# what about...
$ mkimage -B 0x8 -f u-boot.its u-boot.itb
Well, lets just stick with the first one. Okay, now lets dump that .itb file we just made:
$ dumpimage -l u-boot.itb
FIT description: Configuration to load OpenSBI before U-Boot
Created: Thu Nov 27 04:15:19 2025
Image 0 (uboot)
Description: U-Boot
Created: Thu Nov 27 04:15:19 2025
Type: Standalone Program
Compression: uncompressed
Data Size: 583224 Bytes = 569.55 KiB = 0.56 MiB
Architecture: RISC-V
Load Address: 0x80200000
Entry Point: unavailable
Image 1 (opensbi)
Description: OpenSBI fw_dynamic Firmware
Created: Thu Nov 27 04:15:19 2025
Type: Firmware
Compression: uncompressed
Data Size: 115328 Bytes = 112.62 KiB = 0.11 MiB
Architecture: RISC-V
OS: RISC-V OpenSBI
Load Address: 0x80000000
Image 2 (fdt-1)
Description: hifive-unleashed-a00
Created: Thu Nov 27 04:15:19 2025
Type: Flat Device Tree
Compression: uncompressed
Data Size: 19464 Bytes = 19.01 KiB = 0.02 MiB
Architecture: Unknown Architecture
Default Configuration: 'conf-1'
Configuration 0 (conf-1)
Description: hifive-unleashed-a00
Kernel: unavailable
Firmware: opensbi
FDT: fdt-1
Loadables: uboot
Looks good! Only the dates are different. But, wait. The file sizes are different:
Original (built automatically by u-boot): 719973 bytes
Ours: 719871 bytes
Hmm. Lets try to boot it in qemu:
$ nano genimage-sdcard.cfg
image sdcard.img {
size = 128M
hdimage {
gpt = true
}
partition u-boot-spl {
image = "u-boot-spl.bin"
offset = 17K
partition-type-uuid = 5B193300-FC78-40CD-8002-E86C45580B47
}
partition u-boot {
image = "u-boot.itb"
offset = 1041K
partition-type-uuid = 2E54B353-1271-4842-806F-E436D6AF6985
}
}
$ genimage --config genimage-sdcard.cfg --inputpath . --outputpath .
$ qemu-system-riscv64 \
-machine sifive_u,msel=11 \
-m 8G \
-smp 5 \
-display none \
-serial stdio \
-bios u-boot-spl.bin \
-drive file=sdcard.img,if=sd,format=raw
What happens?
Well, if we use the original .itb built by uboot in our sdcard.img, everything works fine. If we use our own which outputs the same details, it doesn’t. We know the files are different sizes. And, if you open them with a hex editor, the differences start pretty early on.
Does anyone have any experience with this? (Not hex editors! Haha. Has anyone already run into this issue and solved it?)
Kind Regards,
- Tim