AccueilWiki i.MX8MP → U-Boot & Boot

U-Boot & Processus de Boot sur i.MX8M Plus

Guide complet du demarrage : Boot ROM, SPL, ATF, U-Boot, Secure Boot, troubleshooting et bring-up de carte custom.

Vue d’ensemble

Le processus de boot du i.MX8M Plus est une chaine multi-etapes ou chaque composant initialise progressivement le materiel et eleve le niveau de fonctionnalite du systeme. Contrairement aux anciens i.MX6/i.MX7, le i.MX8M Plus n’utilise pas de DCD (Device Configuration Data) — l’initialisation de la DDR est entierement geree par le SPL.

Chaine de boot en un coup d’oeil
Boot ROM SPL (OCRAM) ATF (BL31) [OP-TEE] U-Boot (DRAM) Linux Kernel

Chaine de boot complete

EtapeComposantS’execute dansNiveau ARMRole principal
1Boot ROMROM interneEL3Detection media, chargement SPL, verif HAB
2SPLOCRAM (256 KB)EL3Init DDR, chargement ATF + U-Boot
3ATF (BL31)DRAMEL3PSCI, Secure Monitor, transition EL
3bisOP-TEE (optionnel)DRAM (secure)S-EL1Trusted Execution Environment
4U-Boot properDRAMEL2/EL1Bootloader complet, chargement kernel
5Linux KernelDRAMEL1Systeme d’exploitation

Etape 1 : Boot ROM

Le Boot ROM est le tout premier code execute par le processeur apres une mise sous tension ou un reset. Stocke en memoire morte (ROM) a l’interieur du SoC, il ne peut pas etre modifie.

Actions du Boot ROM

  1. Configuration des PLL et des horloges de base du SoC
  2. Initialisation de la SRAM interne (OCRAM / TCM)
  3. Lecture des eFuses pour determiner la config de securite (HABv4) et le peripherique de boot
  4. Detection du media de boot en fonction des pins BOOT_MODE et des eFuses BOOT_CFG
  5. Chargement du SPL (u-boot-spl.bin) depuis le media de boot vers l’OCRAM
  6. Verification HABv4 optionnelle de la signature du SPL
  7. Saut vers le SPL
ℹ️
Difference avec i.MX6/i.MX7 : Sur i.MX8M Plus, le pointeur DCD (Device Configuration Data) est toujours NULL. L’initialisation de la DDR est entierement geree par le SPL, pas par le Boot ROM.

Prerequis materiels pour le Boot ROM

Pendant le power-on, avant la deassert du POR_B, les conditions suivantes doivent etre remplies :

Etape 2 : SPL (Secondary Program Loader)

Le SPL est une version minimaliste de U-Boot, suffisamment compacte pour tenir dans la SRAM interne (OCRAM, ~256 KB). Son role principal est d’initialiser la DRAM externe pour permettre le chargement du bootloader complet.

Actions du SPL

  1. Initialisation UART pour les messages de debug (115200 baud)
  2. Configuration des horloges systeme (PLL, dividers)
  3. Configuration du PMIC (PCA9450 typiquement)
  4. Initialisation DDR/LPDDR4 :
    • Chargement du firmware PHY DDR dans la MCU IRAM/DRAM du controleur
    • Execution de l’entrainement automatique (training) des signaux DDR
    • Parametres de timing depuis lpddr4_timing.c
  5. Chargement de ATF (bl31.bin) et U-Boot proper depuis le media de boot vers la DRAM
  6. Saut vers ATF (BL31)
⚠️
Point critique : Le fichier lpddr4_timing.c contient les parametres de timing specifiques a votre design PCB. Il doit etre genere avec le i.MX 8M Family DDR Tool (Windows) apres avoir passe les stress tests DDR avec succes. Ne jamais reutiliser les timings d’une autre carte sans validation.

Etape 3 : ARM Trusted Firmware (ATF / TF-A)

L’ARM Trusted Firmware (BL31) fournit une base de code de confiance pour l’architecture ARMv8-A. Il s’execute au niveau d’exception le plus privilegie (EL3) et reste resident en memoire pendant toute la duree de vie du systeme.

Responsabilites de BL31

FonctionDescription
PSCIPower State Coordination Interface : gestion ON/OFF/suspend des coeurs CPU
SMC HandlerGestion des appels Secure Monitor Call (transitions secure ↔ normal world)
BL32 initInitialisation optionnelle de OP-TEE (Secure EL1)
BL33 launchSaut vers U-Boot proper (EL2 avec hyperviseur ou EL1 sans)

Compilation de l’ATF

git clone https://github.com/nxp-imx/imx-atf.git -b lf_v2.8 cd imx-atf make PLAT=imx8mp bl31 # Resultat : build/imx8mp/release/bl31.bin

Etape 3bis : OP-TEE (optionnel)

OP-TEE est un systeme d’exploitation securise fournissant un Trusted Execution Environment (TEE) base sur ARM TrustZone. Il s’execute dans le Secure World, isole du monde normal par le materiel.

Fonctionnalites

💡
Quand utiliser OP-TEE ? Pour les applications necessitant un stockage securise de cles (DRM, paiement), l’execution de code de confiance isole, ou la protection anti-rollback du firmware. Dans un contexte industriel classique, OP-TEE est souvent optionnel.

Etape 4 : U-Boot proper

U-Boot proper est le bootloader complet, fonctionnant desormais depuis la DRAM. Il offre une interface en ligne de commande et gere le chargement du noyau Linux.

Fonctionnalites principales

Compilation de U-Boot pour i.MX8MP

# Cloner les sources git clone https://github.com/nxp-imx/uboot-imx.git -b lf_v2023.04 cd uboot-imx # Configurer pour l’EVK make imx8mp_evk_defconfig # Compiler make -j$(nproc) CROSS_COMPILE=aarch64-linux-gnu- # Resultats : # u-boot-spl.bin (SPL) # u-boot-nodtb.bin + dtb (U-Boot proper)

Etape 5 : Noyau Linux

U-Boot charge le noyau (Image), le device tree (.dtb) et optionnellement un initramfs en DRAM, puis transfere le controle au noyau via booti.

# Commande typique executee par U-Boot load mmc 2:1 ${loadaddr} Image load mmc 2:1 ${fdt_addr} imx8mp-evk.dtb setenv bootargs ‘console=ttymxc1,115200 root=/dev/mmcblk2p2 rootwait rw’ booti ${loadaddr} – ${fdt_addr}

Structure de flash.bin

L’outil imx-mkimage assemble tous les composants binaires en un seul fichier flash.bin qui est flashe sur le media de boot.

Composition de flash.bin
u-boot-spl.bin
SPL (Secondary Program Loader)
DDR PHY Firmware
lpddr4_pmu_train_1d/2d_imem/dmem
bl31.bin
ARM Trusted Firmware (ATF)
tee.bin
OP-TEE (optionnel)
u-boot-nodtb.bin + DTB
U-Boot proper + Device Tree
HDMI FW
Firmware HDMI (optionnel)

Generation avec imx-mkimage

# Cloner imx-mkimage git clone https://github.com/nxp-imx/imx-mkimage.git -b lf_v2023.04 # Copier les binaires dans iMX8M/ cp u-boot-spl.bin iMX8M/ cp u-boot-nodtb.bin iMX8M/ cp imx8mp-evk.dtb iMX8M/ cp bl31.bin iMX8M/ cp lpddr4_pmu_train_*.bin iMX8M/ # Generer flash.bin make SOC=iMX8MP flash_evk # Avec DTB supplementaires (overlays) make SOC=iMX8MP flash_evk supp_dtbs= »overlay.dtbo » # Pour FlexSPI (QSPI NOR) make SOC=iMX8MP flash_evk_flexspi

Boot depuis differents medias

Carte SD (USDHC)

# Flasher flash.bin sur carte SD (offset 32 KB) sudo dd if=flash.bin of=/dev/sdX bs=1k seek=32 conv=fsync

Le Boot ROM recherche l’IVT (Image Vector Table) a l’offset 32 KB sur la carte SD.

eMMC

# Flasher sur la partition boot de l’eMMC echo 0 > /sys/block/mmcblk2boot0/force_ro dd if=flash.bin of=/dev/mmcblk2boot0 bs=1k seek=32 conv=fsync echo 1 > /sys/block/mmcblk2boot0/force_ro # Ou sur la partition utilisateur dd if=flash.bin of=/dev/mmcblk2 bs=1k seek=32 conv=fsync

Secondary Image Boot : L’eMMC supporte le boot avec fallback automatique :

BOOT_PARTITION_ENABLEComportement
0x1Boot partition 1 d’abord, fallback sur partition 2
0x2Boot partition 2 d’abord, fallback sur partition 1

QSPI NOR Flash (FlexSPI)

Raw NAND Flash

Switches de boot & eFuses

Pins BOOT_MODE[1:0]

BOOT_MODE[1:0]ModeDescription
00Boot from FusesConfig de boot lue uniquement depuis les eFuses
01Serial DownloaderMode recovery USB/UART (UUU)
10Internal BootMode normal — le plus courant
11ReserveNon utilise

Sur l’EVK NXP, ces pins correspondent aux switches SW3-2 (BOOT_MODE0) et SW3-3 (BOOT_MODE1).

BT_FUSE_SEL : GPIO vs eFuses

En mode Internal Boot (BOOT_MODE = 10), le fuse BT_FUSE_SEL (adresse 0x460, bit 4) determine la source de configuration :

BT_FUSE_SELSourceUsage
0 (defaut)Pins GPIO (DIP switches)Developpement
1eFuses uniquementProduction

Registres BOOT_CFG (eFuses)

Adresse OCOTPRegistreUsage
0x470BOOT_CFG0Selection du peripherique de boot (bits 10:9 pour USDHC)
0x480BOOT_CFG1Configuration specifique au peripherique
0x490BOOT_CFG2Configuration additionnelle
0x4A0BOOT_CFG3Configuration additionnelle
0x4B0BOOT_CFG4Configuration additionnelle

Programmation des fuses

⚠️
ATTENTION : La programmation des eFuses est IRREVERSIBLE. Une fois un fuse programme, il ne peut plus etre modifie. Toujours verifier deux fois avant de programmer.
# Lire un fuse fuse read <bank> <word> # Programmer un fuse (IRREVERSIBLE !) fuse prog -y <bank> <word> <valeur_hex> # Exemple : activer BT_FUSE_SEL (boot depuis fuses) fuse prog -y 1 3 0x00000010

Environnement U-Boot

Variables principales

VariableDescriptionValeur typique
bootcmdCommande executee au boot automatiquerun distro_bootcmd
bootargsArguments passes au noyau Linuxconsole=ttymxc1,115200 root=…
bootdelayDelai avant boot auto (secondes)2
fdtfileFichier Device Tree a chargerimx8mp-evk.dtb
fdt_addrAdresse memoire du DTB0x43000000
loadaddrAdresse de chargement du kernel0x40480000
fdt_overlayListe des overlays DT a appliqueroverlay-cam1.dtbo
boot_targetsListe ordonnee des cibles de bootmmc1 mmc2 usb0

Gestion de l’environnement

# Afficher toutes les variables printenv # Afficher une variable specifique printenv bootcmd # Definir une variable (RAM uniquement) setenv bootargs ‘console=ttymxc1,115200 root=/dev/mmcblk2p2 rootwait’ # Sauvegarder en memoire persistante (eMMC/SD) saveenv # Restaurer les valeurs par defaut env default -a saveenv

Commandes essentielles U-Boot

Informations systeme

# Infos sur la carte bdinfo # Version U-Boot version # Infos CPU et clocks clocks # Status MMC mmc info mmc list mmc dev 2 # Selectionner l’eMMC # Status reseau mdio list

Memoire

# Lire la memoire (dump hex) md.b 0x40000000 0x100 # Ecrire en memoire mw.l 0x40000000 0xDEADBEEF # Test memoire mtest 0x40000000 0x80000000

Chargement de fichiers

# Charger depuis MMC (partition 1 du device 2) load mmc 2:1 ${loadaddr} Image load mmc 2:1 ${fdt_addr} imx8mp-evk.dtb # Charger via TFTP setenv serverip 192.168.1.100 setenv ipaddr 192.168.1.50 tftp ${loadaddr} Image tftp ${fdt_addr} imx8mp-evk.dtb # Charger depuis USB usb start load usb 0:1 ${loadaddr} Image

Boot

# Boot Linux (Image + DTB) booti ${loadaddr} – ${fdt_addr} # Boot avec initramfs booti ${loadaddr} ${initrd_addr}:${filesize} ${fdt_addr} # Boot FIT image bootm ${loadaddr}

I2C, GPIO, eFuses

# Scanner un bus I2C i2c bus i2c dev 0 i2c probe # Lire un registre I2C i2c md 0x25 0x00 0x10 # GPIO gpio status gpio set GPIO5_3 gpio clear GPIO5_3 # eFuses fuse read 1 3

Distro Boot

Le mecanisme Distro Boot permet la decouverte automatique du media de boot. U-Boot itere sur les cibles definies dans boot_targets et execute les scripts de boot trouves.

# Configuration type bootcmd=run distro_bootcmd; run bsp_bootcmd distro_bootcmd=for target in ${boot_targets}; do run bootcmd_${target}; done boot_targets=usb0 mmc1 mmc2

Pour chaque cible, U-Boot cherche un script boot.scr ou un fichier extlinux/extlinux.conf sur la partition de boot.

Exemple extlinux.conf

label linux kernel /Image fdt /imx8mp-custom-board.dtb append console=ttymxc1,115200 root=/dev/mmcblk2p2 rootwait rw

Device Tree Overlays

Les overlays permettent de modifier le Device Tree principal sans le recompiler. Ideal pour activer/desactiver des peripheriques ou configurer des options materielles (camera, display, codec audio…).

# Dans U-Boot : definir les overlays setenv fdt_overlay ‘overlay-cam1-ov5640.dtbo overlay-lvds0.dtbo’ saveenv # Application manuelle dans U-Boot load mmc 2:1 ${fdt_addr} imx8mp-evk.dtb fdt addr ${fdt_addr} fdt resize 8192 load mmc 2:1 0x44000000 overlay-cam1-ov5640.dtbo fdt apply 0x44000000
💡
Bonne pratique : Pour une carte custom, ne modifiez pas directement le DT de l’EVK. Creez un nouveau fichier .dts qui inclut le DT du SoC et ajoutez vos specificites. Utilisez les overlays pour les options configurables.

Initialisation DDR

L’initialisation de la DDR est l’etape la plus critique du bring-up. Elle est effectuee par le SPL et utilise un firmware Synopsys pour le PHY DDR.

Workflow DDR

  1. Telecharger le DDR Tool NXP (Windows) depuis la NXP Community
  2. Connecter la carte en mode Serial Downloader (BOOT_MODE = 01)
  3. Configurer les parametres DDR (type, frequence, topology, nombre de CS)
  4. Executer le DDR training automatique
  5. Lancer les stress tests (lecture/ecriture intensive, patterns)
  6. Valider tous les tests (OBLIGATOIRE)
  7. Exporter le fichier lpddr4_timing.c
  8. Integrer dans les sources U-Boot de votre carte

Fichiers DDR PHY Firmware

4 fichiers binaires sont necessaires pour le firmware du PHY DDR (inclus dans le package firmware-imx de NXP) :

⚠️
Ne jamais sauter le stress test DDR. Un echec silencieux du training DDR peut causer des corruptions de donnees aleatoires, des kernel panics intermittents, ou des freezes sous charge — des problemes extremement difficiles a debugger apres coup.

Secure Boot (HABv4)

Le High Assurance Boot v4 (HABv4) est le mecanisme de boot securise du i.MX8M Plus. Il utilise la cryptographie a cle publique (RSA) pour verifier l’integrite et l’authenticite de chaque etape de la chaine de boot.

Arbre PKI (Public Key Infrastructure)

Hierarchie des cles HABv4
SRK (Super Root Keys)
Jusqu’a 4 cles racine — hash programme dans les eFuses
CSF Keys
Signent les commandes CSF
IMG Keys
Signent les images de boot

Mise en oeuvre etape par etape

EtapeActionOutil
1Generer l’arbre PKI complet (SRK, CSF, IMG keys)hab4_pki_tree.sh (CST)
2Generer la table SRK et le hash pour les eFusessrktool
3Creer le fichier CSF (Command Sequence File)Editeur texte
4Signer flash.bin avec les clescst (Code Signing Tool)
5Tester le boot signe en mode OPENhab_status dans U-Boot
6Programmer les fuses SRK (IRREVERSIBLE)fuse prog
7Verifier : aucun evenement HABhab_status
8Fermer le device (IRREVERSIBLE)fuse prog SEC_CONFIG

Generation de la table SRK

# Generer l’arbre PKI cd <CST_install>/keys ./hab4_pki_tree.sh # Generer la table SRK et les hash eFuses srktool –hab_ver 4 –table SRK_table.bin –efuses SRK_efuses.bin \ –digest sha256 \ –certs SRK1_sha256_2048_65537_v3_ca_crt.pem,\ SRK2_sha256_2048_65537_v3_ca_crt.pem,\ SRK3_sha256_2048_65537_v3_ca_crt.pem,\ SRK4_sha256_2048_65537_v3_ca_crt.pem

Programmation des fuses SRK

# Programmer les 8 mots SRK (banques 6-7, mots 0-3) — IRREVERSIBLE ! fuse prog -y 6 0 0xEA2F0B50 fuse prog -y 6 1 0x871167F7 fuse prog -y 6 2 0xF5CECF5D fuse prog -y 6 3 0x364727C3 fuse prog -y 7 0 0x8DD52832 fuse prog -y 7 1 0xF158F65F fuse prog -y 7 2 0xA71BBE78 fuse prog -y 7 3 0xA3AD024A # Verifier qu’aucun evenement HAB n’est genere hab_status # FERMER le device (IRREVERSIBLE — seulement apres validation complete !) fuse prog -y 1 3 0x02000000
⚠️
Pieges critiques du Secure Boot :
  • Ne JAMAIS fermer le device avant d’avoir valide que le boot signe fonctionne parfaitement en mode OPEN
  • Erreur de SRK = device brick : les eFuses sont irreversibles
  • Couvrir TOUTES les images de flash.bin avec une signature
  • HSM recommande pour la gestion des cles privees en production
  • Firmware HDMI/DP : inclure la commande Unlock dans le CSF du SPL si ces controleurs sont desactives

Falcon Mode (boot rapide)

Le Falcon Mode permet de gagner environ 4 secondes en faisant sauter le SPL directement au noyau Linux, contournant U-Boot proper.

Chaine de boot Falcon

Boot ROM SPL ATF Linux Kernel (U-Boot proper bypasse)

Optimisations complementaires

OptimisationGain
Falcon Mode (bypass U-Boot proper)~4 secondes
Ajouter quiet aux bootargs du kernel~3 secondes
Reordonner les scripts systemd~600 ms
Touche ‘c’ au boot pour forcer le mode normalFallback U-Boot

Reference NXP : AN14641 — Fast and Secure Boot using Falcon Mode on i.MX 8M

Recovery avec UUU

UUU (Universal Update Utility) est l’outil open source de NXP pour recuperer les cartes i.MX via USB. Il remplace l’ancien MfgTool.

Procedure de recovery

  1. Configurer les DIP switches en mode Serial Downloader (BOOT_MODE = 01)
  2. Connecter le cable USB OTG entre la carte et le PC hote
  3. Le device doit apparaitre comme « NXP Semiconductors SE Blank M850 »
  4. Lancer UUU :
# Installer UUU # Linux : telecharger depuis github.com/nxp-imx/mfgtools/releases # Flasher flash.bin sur eMMC sudo uuu -b emmc flash.bin # Flasher une image complete (bootloader + rootfs) sudo uuu -b emmc_all flash.bin rootfs.wic # Charger un bootloader en RAM (debug) sudo uuu flash.bin
ℹ️
Compatibilite UUU : Utiliser UUU v1.5.11+ pour les SDK bases sur le noyau 5.15.32. Les SDK bases sur le noyau 5.10.72 fonctionnent avec UUU v1.4.193.

Troubleshooting

Aucune sortie UART au demarrage

Cause possibleSolution
Fils Tx/Rx inversesVerifier le croisement des connexions serie
Mauvais baudrateUtiliser 115200 8N1
Oscillateur 24 MHz KOMesurer avec sonde active (pas passive !)
Oscillateur 32,768 kHz KOVerifier le quartz RTC
Alimentation defaillanteMesurer les tensions au plus pres du SoC
Sequence power-up incorrecteVerifier la datasheet (power sequencing)

Echec DDR Training

Cause possibleSolution
Parametres de timing incorrectsRegenerer lpddr4_timing.c avec DDR Tool
Stress test non valideRelancer les stress tests complets
Routage PCB DDR defectueuxVerifier topologie en T, longueur des pistes, stubs
Tension VDDQ incorrecteMesurer les alimentations DDR
Composants DDR incompatiblesVerifier la liste de compatibilite NXP

Boot SD echoue

Cause possibleSolution
Mauvais offset de flashUtiliser seek=32 (32 KB)
DIP switches incorrectsVerifier la config pour le mode boot SD
Carte SD incompatibleTester avec une carte SD standard (pas UHS-II)
flash.bin corrompuRegenerer avec imx-mkimage

Warm reboot echoue (1 fois sur 20)

Cause possibleSolution
Reset PMIC insuffisantVerifier le signal PMIC_ON_REQ et la sequence de reset
Watchdog timeoutAjuster le timeout watchdog dans U-Boot/Linux
DDR non re-entraineeS’assurer que le SPL re-execute le DDR training au warm boot

Linux crash quand M7 tourne deja

Cause possibleSolution
Conflit de peripheriquesS’assurer que le DT Linux desactive les peripheriques utilises par M7
Acces registre sans clockInitialiser les clocks avant tout acces peripherique sur M7
Memoire partagee mal configureeReserver la region memoire M7 dans le DT Linux

JTAG non fonctionnel

Bring-up carte custom

Checklist de bring-up

  1. Rapport de tensions : Mesurer TOUTES les alimentations au plus pres du SoC avant la premiere mise sous tension. Verifier VDD_ARM, VDD_SOC, NVCC_DRAM, etc.
  2. Oscillateurs : Verifier 24 MHz et 32,768 kHz avec une sonde active (une sonde passive peut empecher le demarrage du 24 MHz)
  3. Console UART : Connecter avant la premiere mise sous tension
  4. DDR stress test : Obligatoire, ne pas sauter cette etape
  5. Boot minimal : Tester le boot SD avec l’image EVK modifiee pour votre carte
  6. Activation des peripheriques : Un par un, via Device Tree

Conception PCB : points critiques

ElementRecommandation
Condensateurs decouplage0201/0402, a moins de 50 mils des vias d’alimentation
Routage DDR dataRoutage direct SoC → SDRAM, minimum de stubs
Routage DDR addr/cmdTopologie en T, branches de meme longueur
Terminaison DDRTerminaison parallele au point de branchement
JTAGPin JTAG_MOD maintenue a 0 (pull-down)
BOOT_MODEDIP switches accessibles pour le debug

Adaptation du Device Tree

💡
Ne pas modifier les DT de l’EVK/SoM directement. Structure recommandee :
  • imx8mp.dtsi — fichier SoC (NXP, ne pas toucher)
  • imx8mp-som.dtsi — fichier SoM (si applicable)
  • imx8mp-votre-carte.dts — votre carte custom
Les fichiers DT sont dans arch/arm64/boot/dts/freescale/

Adaptation du BSP Yocto

Ressources

Documentation NXP

Depots Git

Outils

Besoin d’aide pour le bring-up de votre carte i.MX8MP ?

DDR training, adaptation BSP, Secure Boot, integration FreeRTOS M7 — je vous accompagne sur toute la chaine de boot.

Discuter de votre projet →