January 26, 2026

Allwinner H5 chip - Making a stripped down boot setup

First a note for myself. I am doing my work in /Projects/ARM-sources/h5 and the final result is in the Makefile.

The best part of this (once you get to the conclusion) is I now have a recipe for making a bootable SD card from the file u-boot-sunxi-with-spl.bin that results from building U-boot from source.

I want to extract "johang.bin" from boot-orange_pi_pc2.bin. This will be the equivalent of u-boot-sunxi-with-spl.bin that I would get if I build U-boot from source.
I do this:

dd if=boot-orange_pi_pc2.bin of=johang.bin bs=1024 skip=8 count=2040
The count is going to extract more than I need. Looking at a recent U-boot build from source, I see:
-rw-r--r-- 1 tom tom 1004573 Jan 21 17:14 u-boot-sunxi-with-spl.bin
This is somewhat over 1M. My extract pulls 2M-8K (2048-8 1K blocks).

Build our template image

This involves a fight with Gnu parted, as well as some unsuspected surprises. After trying what I thought would work and finding that it didn't, I backed off and tried a variety of things to slowly sneak up on what I really wanted to do.
BOOT = boot-orange_pi_pc2.bin
SD = /dev/sdg

dd if=$(BOOT) of=johang.bin bs=1024 skip=8 count=2040
dd if=/dev/zero of=$(SD) bs=1M count=64
dd if=johang.bin of=$(SD) bs=1024 seek=8
This SD card worked and would boot up U-boot. Of course saveenv does not, as there is no partition table, and thus no FAT partition.
Then I tried this, which also worked as the above:
dd if=$(BOOT) of=johang.bin bs=1024 skip=8 count=2040
dd if=/dev/zero of=test.bin bs=1024 count=2048
dd if=johang.bin of=test.bin bs=1024 seek=8
dd if=/dev/zero of=$(SD) bs=1M count=64
dd if=test.bin of=$(SD)

Now let's add a disk label. An MSDOS disk label (better known as an MBR or "master boot record") is 512 bytes in size (one sector) and is well documented in many places. It ends with a 2 byte signature: 0x55, 0xAA.

We allow 8K for the label (16 sectors), not because we are generous, but because the Allwinner h5 bootrom only looks for something to boot at 8K boundaries. As far as I know, it checks at offset 0, but rejects the MSDOS label it finds there -- then it goes on to the 8K boundary and is able to fetch the U-boot SPL from there.

#dd if=/dev/zero of=test.bin bs=1024 count=2048
dd if=/dev/zero of=test.bin bs=1024 count=4096
parted -s test.bin mklabel msdos
parted -s test.bin mkpart primary fat32 -- 2MiB 3MiB
dd if=johang.bin of=test.bin bs=1024 seek=8 conv=notrunc
parted -s test.bin print
This works fine when I put the card into the OrangePi and boot it.

Notice two things. One is that I need to mage the image bigger (I now use 4M rather than 2M). This is because parted will complain if partition limits are beyond the end of the file. The other is the "notrunc" option when I write the U-boot image (johang.bin) into the middle of the file. Without this, the file gets chopped off and once again we have a disklabel with pointers beyond the end of the file.

The final working method

I don't know what I did wrong. That is the problem with typing commands at the command line rather than using scripts. The following yields a working image that boots up U-boot just fine and saveenv works.
rm -f vfat.img
fallocate -v -l 1MiB vfat.img
mkfs.vfat vfat.img

rm -f test.bin
#dd if=/dev/zero of=test.bin bs=1024 count=2048
dd if=/dev/zero of=test.bin bs=1024 count=4096
parted -s test.bin mklabel msdos
parted -s test.bin mkpart primary fat32 -- 2MiB 3MiB
dd if=johang.bin of=test.bin bs=1024 seek=8 conv=notrunc
dd if=vfat.img of=test.bin bs=1024 seek=2048 conv=notrunc
parted -s test.bin print
mkfs.vfat vfat.img
We do end up with a 4M image, which could be just 3M, but that is the least of my worries.


Have any comments? Questions? Drop me a line!

Tom's electronics pages / tom@mmto.org