Custom U-Boot (HAB + FIT signature) for i.MX 8M Plus EVK
This guide walks you through cross-compiling a custom imx-boot
bundle from source and flashing it onto an i.MX 8M Plus EVK. The
reference matches the pins nxp-imx/meta-imx ships at
scarthgap-6.6.36-2.1.0 (uboot-imx lf_v2024.04, imx-atf lf_v2.10,
imx-mkimage lf-6.6.36_2.1.0, firmware-imx 8.25-27879f8) with HAB and
FIT signature support enabled, and replaces the bootloader Avocado
would otherwise pull in.
Prerequisites
- Linux host (Ubuntu 22.04+, Fedora 39+) — or macOS with Docker Desktop.
- Docker running.
- Avocado CLI: see docs.peridio.com.
- An i.MX 8M Plus EVK in serial-download (USB-OTG) mode for flashing
via
uuu-emmc.
Initialize
avocado init --reference uboot-custom-imx8mp-evk uboot-imx8mp-evk
cd uboot-imx8mp-evk
Install
avocado install -f
This pulls the Avocado SDK container and installs nativesdk-bc,
nativesdk-bison, nativesdk-flex, nativesdk-openssl,
nativesdk-dtc, nativesdk-util-linux — the build deps needed by
U-Boot, TF-A, and imx-mkimage.
Build
avocado build
The build runs uboot-compile.sh inside the SDK container, which:
- Saves
CROSS_COMPILE/ARCHfrom the SDK env, then unsets the userspaceCC,CFLAGS,LDFLAGSexports that fight the U-Boot and TF-A build systems (same trick the Linux kernel reference uses). - Clones
uboot-imx(branchlf_v2024.04, SRCREVde16f4f1),imx-atf(branchlf_v2.10, SRCREV28affcae),imx-mkimage(branchlf-6.6.36_2.1.0, SRCREV4622115c), and downloadsfirmware-imx-8.25-27879f8.binfrom NXP's mirror — the exact pins meta-imx ships at scarthgap-6.6.36-2.1.0. - Appends
patches/avocado.cfg+patches/env-mmc.cfgontoimx8mp_evk_defconfig, and adds#include "avocado-fit-signature.dtsi"toimx8mp-evk-u-boot.dtsiso the control DTB carries a placeholder /signature node. - Builds TF-A BL31, builds U-Boot, generates a redundant
uboot.envfrompatches/avocado-imx8mp-evk.txt. - Stages the binaries into
iMX8M/and runsmake SOC=iMX8MP flash_evkto produceflash.bin(==imx-boot).
uboot-install.sh then drops flash.bin and uboot.env into
$AVOCADO_RUNTIME_BUILD_DIR, so the stone bundle assembled by
avocado build carries our bootloader.
You can also rebuild only the bootloader without re-assembling the runtime:
avocado sdk compile uboot
Inject a FIT signing pubkey (the "replace later" workflow)
The bootloader you just built has /signature/key-rt-prod as a
placeholder — empty rsa,modulus etc. To actually have it verify FIT
images, populate that node with your dev pubkey:
avocado sdk run -E -- bash insert-fit-pubkey.sh
avocado build
insert-fit-pubkey.sh:
- Generates
keys/dev.key+keys/dev.crtif missing. - Builds a throwaway FIT image referencing
key-name-hint = "dev". - Runs
mkimage -F -K …so mkimage extracts the pubkey fromkeys/dev.keyand patches it into the placeholder /signature node in the already-built U-Boot DTB — no full U-Boot rebuild. - Re-runs
imx-mkimageto fold the patched DTB back into a freshflash.bin.
Re-running avocado build then re-stages the updated bootloader in the
runtime build dir.
To rotate the key, drop a new keys/dev.key (or change KEY_NAME in
the script) and re-run insert-fit-pubkey.sh + avocado build. The
core bootloader binary doesn't change — only the pubkey block in the
control DTB.
To sign your real FIT images (kernel + dtb + initramfs) for this bootloader to accept:
mkimage -F -k keys -r <fit-image.itb>
Provision the EVK
Put the EVK in serial-download mode (set boot DIPs SW4 to
0011 0010 0010 1000, the documented serial-download position — see
the EVK user manual; do not press an arbitrary BOOT+RESET combo) and
plug a USB-C cable into the OTG port:
avocado provision -r dev --profile uuu-emmc
uuu hands flash.bin to the boot ROM via SDPS, then writes the OS
bundle (rootfs / initramfs / kernel) to eMMC. Reset the board with
DIPs back to eMMC boot — your custom HAB-ready U-Boot runs first.
Closing HAB (production-only)
The build leaves HAB open — i.e., this flash.bin will boot on any imx8mp without signature checks. Closing HAB is a one-way fuse blow: do not do this on a dev board you want to recover.
The full procedure is documented in NXP's i.MX Secure Boot on AHAB and HAB CST guide. Sketch:
- Generate SRK / CSF / IMG keys with NXP's CST.
- Run
cst -i csf-spl.txtandcst -i csf-uboot.txtagainst theflash.binproduced by this reference. Use theimx_logblock at the start of the build output to find the load addresses CST needs. - Append the resulting CSF blobs to
flash.binat the offsets the first stage reports. - Verify with
hab_statusfrom the U-Boot prompt — it should report "No HAB Events Found!" before you close. - Blow the SRK_HASH fuse via
fuse prog. Once closed, only flash.bin binaries signed by your SRK chain will boot.
Customize
Different NXP release line
Bump the branch + SRCREV pairs at the top of uboot-compile.sh to
match the meta-imx tag for the release line you want. The canonical
source is the matching recipes-bsp/{imx-atf,u-boot,imx-mkimage}/*.bb
and recipes-bsp/firmware-imx/firmware-imx-*.inc in
nxp-imx/meta-imx — open the
files at the tag for your release line and copy the
SRCBRANCH / SRCREV / firmware-imx PV + IMX_SRCREV_ABBREV values
verbatim.
Different i.MX 8M variant
Swap UBOOT_DEFCONFIG, ATF_PLATFORM, MKIMAGE_SOC, and
MKIMAGE_TARGET in uboot-compile.sh. Check
imx-mkimage/iMX8M/soc.mak for the available targets and the staging
filenames each one expects.
Customize the boot env
Edit patches/avocado-imx8mp-evk.txt. The format is mkenvimage(1) —
each line is a key=value U-Boot env entry.
Different supported_targets
This reference is hard-coded to imx8mp-evk because of the imx-mkimage
target name. To support multiple boards, switch on
{{ avocado.target.board }} in avocado.yaml and gate the
uboot-compile.sh choices off $AVOCADO_TARGET.