Boot a signed Zephyr image with U-Boot on Arm Cortex-A
Introduction
Understand where U-Boot verifies Zephyr in the Cortex-A boot chain
Set up the host tools for your target
Build a Zephyr image that U-Boot can start
Create signing keys and sign the Zephyr image into a FIT
Build U-Boot with the public key and a boot command that fails closed
Boot the signed Zephyr FIT with U-Boot on QEMU or the TI AM62L EVM
(Optional) Test that U-Boot refuses a wrong key and a tampered image
Review the Zephyr FIT verification boundary and production needs
Next Steps
Boot a signed Zephyr image with U-Boot on Arm Cortex-A
Introduction
Understand where U-Boot verifies Zephyr in the Cortex-A boot chain
Set up the host tools for your target
Build a Zephyr image that U-Boot can start
Create signing keys and sign the Zephyr image into a FIT
Build U-Boot with the public key and a boot command that fails closed
Boot the signed Zephyr FIT with U-Boot on QEMU or the TI AM62L EVM
(Optional) Test that U-Boot refuses a wrong key and a tampered image
Review the Zephyr FIT verification boundary and production needs
Next Steps
Understand the verification boundary
You’ve configured U-Boot to verify the Zephyr payload, the last link in the boot chain. U-Boot reads zephyr-a.itb and verifies conf-1 with the embedded public key for key-a. It checks the payload hash before jumping to ZEPHYR_ADDR.
If you ran the optional
refusal tests
, you also confirmed two rejection cases. The wrong-key Flattened Image Tree (FIT) fails with Failed to verify required signature 'key-key-a'. The modified payload fails with Bad hash value for 'hash-1'. Neither starts Zephyr.
The earlier stages aren’t authenticated against your key in either setup. QEMU loads u-boot.bin directly, without a boot ROM, security firmware, or eFuses to authenticate it.
The AM62L evaluation module (EVM) has those earlier stages, but you’ve left it in TI’s High Security, Field Securable (HS-FS) development state. In this state, the ROM and vendor firmware check boot files but accept any signing key. The U-Boot banner identifies it as SoC: AM62LX SR1.1 HS-FS. Provisioning your key into the one-time-programmable eFuses moves the device to High Security, Security Enforced (HS-SE).
On the EVM, the trusted public key is inside u-boot.img on an unprotected File Allocation Table (FAT) partition. Anyone who can replace that file can replace the key and boot command. Production needs an authenticated U-Boot and controls that prevent bypassing its verification step.
What you need for production
For production, ensure that you complete the following steps:
Fuse your key and move to the production state
TI’s one-time-programmable (OTP) Keywriter tool, called Keywriter Lite on the AM62L, burns the public-key hash into the eFuses and moves the chip to HS-SE. You then re-sign tiboot3.bin, tispl.bin, and u-boot.img with that key.
The ROM and security firmware then require boot files signed with your key, including U-Boot. This authenticates the U-Boot image containing the FIT public key. Key provisioning is vendor-specific and isn’t covered in these steps.
Keep the environment built in
bootcmd selects the autoboot command. preboot defines zboot and the a, b, and t wrappers before autoboot starts.
Both builds use CONFIG_ENV_IS_NOWHERE=y: you added it for QEMU, and the AM62L default configuration supplies it. This prevents saveenv from writing a persistent environment, so boot settings are loaded from the binary that you built. Check that the .config for your board includes the same setting.
Don’t enable CONFIG_ENV_IS_IN_FAT for this boot configuration. It stores the environment in uboot.env on the boot media. A saved environment can override bootcmd and preboot, allowing someone with write access to the card to bypass verification.
Lock the console
With CONFIG_BOOTDELAY=3, someone with serial-console access can interrupt autoboot and run fatload and go without verification. Set CONFIG_BOOTDELAY=-2 to remove the delay and keyboard check, or use CONFIG_AUTOBOOT_KEYED to require a known string to interrupt autoboot.
These settings cover only the countdown. If bootcmd returns after rejecting an image, U-Boot still opens the => prompt. In a production build, add reset after the refusal echo in zboot. This ensures that a failed boot restarts the board instead of opening the console.
Protect production keys and sign during release
You used sha256,rsa2048. The boot chain of the AM62L uses sha512,rsa4096. To use the latter for your FIT:
- Generate keys with
rsa_keygen_bits:4096. - Set
algo = "sha512,rsa4096"in bothzephyr-a.itsandkey.its. - Confirm that
$UBOOT_OUT/.configincludesCONFIG_SHA512=y, adding it to the configuration fragment if needed.
Generate production keys in a hardware security module (HSM), or at least away from the build host. Sign during the release process and restrict private-key access to that process.
Adapt the workflow to another Cortex-A board
If you want to use another Cortex-A board, start by updating the target values and paths in your environment file:
BOARDis the Zephyr board identifier, fromwest boardsor the Workbench board list. The board needs the two settings from Build a Zephyr image that U-Boot can start : the Non-secure world and the arm64 image header.ZEPHYR_ADDRis the start of the memory node that the device tree of the board selects aszephyr,sram. It’s the link address of Zephyr, the FITloadandentry, and thegotarget, so one value serves all three.FIT_ADDRis any free address clear ofZEPHYR_ADDRand of the firmware regions. Otherwise,bootm loadoscopies Zephyr over the FIT it’s still reading.BOOT_DEVis the U-Boot device and partition that hold the files.mmc 1:1is the first partition of the SD card on the AM62L EVM, whilemmc 0is the eMMC.mmc listat the U-Boot prompt shows the numbering of your board.UBOOT_DEFCONFIGselects the U-Boot default configuration of the board. Check forCONFIG_FIT=y,CONFIG_FIT_SIGNATURE=y, andCONFIG_RSA=y. Add missing settings to the U-Boot configuration fragment . Disable legacy images with# CONFIG_LEGACY_IMAGE_FORMAT is not set.UBOOT_SRC,CROSS, andUBOOT_CCpoint at the U-Boot source and the compiler that builds it.SDK,PREBUILT, andSYSROOTare added when they come from a vendor SDK, as on the AM62L.BOOT_IMGis the boot volume thatmcopywrites into: the card image on the EVM, the disk image in QEMU, each with the@@offset of its FAT partition.
Also adapt the U-Boot build command and boot-media preparation. The build inputs depend on the target: EXT_DTB for QEMU, or BL1, BL31, TEE, and BINMAN_INDIRS for the AM62L EVM. Output names also vary, often including u-boot.img or u-boot.itb and a Secondary Program Loader (SPL) file. Follow the requirements of the target for media layout, boot switches, and console access.
Check how the target obtains its control device tree. CONFIG_DEVICE_TREE_INCLUDES adds the key node when the tree is built from source with CONFIG_OF_SEPARATE=y or CONFIG_OF_EMBED=y, as on the AM62L EVM.
For a board using a tree from a prior stage (CONFIG_OF_BOARD=y), follow the QEMU approach: merge signature.dtsi into an exported tree and pass it to the build with EXT_DTB=.
Reuse the FIT signing and verification workflow, adapting the target values in the FIT source and boot command as needed.
What you’ve accomplished
You’ve established verification of the Zephyr payload and learned how you can extend the workflow to production and to another Cortex-A board.
Before using this approach in production, authenticate the earlier boot stages. Also protect the boot environment and console and move signing into a controlled release process.
To sign your own application for the same target, point data in zephyr-a.its to its zephyr.bin and sign the FIT again. To use another Cortex-A board, adapt the environment, build inputs, and boot media using the checklist in this section.