Portage et configuration d'U-Boot pour le processeur STM32MP157

Le processeur STM32MP157 de STMicroelectronics, basé sur une architecture hétérogène double cœur Cortex-A7 et un cœur Cortex-M4, nécessite une phase de portage spécifique du chargeur d'amorçage U-Boot pour s'adapter aux différentes configurations matérielles. Cette procédure détaille l'adaptation du code source officiel pour un système embarqué personnalisé doté de 1 Go de RAM et d'un stockage eMMC.

1. Préparation du code source et application des patchs

Après avoir extrait l'archive du code source d'U-Boot (version 2020.01), il est indispensable d'appliquer les correctifs fournis par le constructeur pour garantir la compatibilité avec l'architecture STM32MP1. Utilisez la commande suivante pour intégrer tous les fichiers de patch situés dans le répertoire parent :

find ../ -name "*.patch" -type f -exec patch -p1 -i {} \;

2. Création d'une configuration de plateforme personanlisée

Pour ne pas altérer les fichiers génériques, nous créons une configuration spécifique à notre carte en nous basant sur le profil "trusted" de ST :

cp configs/stm32mp15_trusted_defconfig configs/stm32mp15_custom_defconfig

L'étape suivante consiste à adapter l'arbre de périphériques (Device Tree). Les fichiers DTS doivent être dupliqués et renommés :

  • cp arch/arm/dts/stm32mp15xx-dkx.dtsi arch/arm/dts/stm32mp15xx-custom.dtsi
  • cp arch/arm/dts/stm32mp157a-dk1.dts arch/arm/dts/stm32mp157a-custom.dts
  • cp arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi arch/arm/dts/stm32mp157a-custom-u-boot.dtsi

Dans stm32mp157a-custom.dts, mettez à jour l'inclusion du fichier d'en-tête pour pointer vers votre nouveau fichier .dtsi et modifiez la propriété model.

Dans le fichier stm32mp15xx-custom.dtsi, il est crucial d'ajuster la capacité de la mémoire vive si elle diffère du modèle de référence (512 Mo). Pour 1 Go de RAM, modifiez le nœud memory comme suit :

memory@c0000000 {
    device_type = "memory";
    reg = <0xc0000000 0x40000000>; /* 1 Go de RAM */
};

Enfin, mettez à jour le Makefile dans arch/arm/dts/ pour inclure votre nouveau binaire d'arbre de périphériques (stm32mp157a-custom.dtb) dans la liste de compilation.

3. Configuration de l'environnement de compilation

Modifiez le Makefile principal à la racine du projet pour définir l'architecture et le préfixe de la chaîne de compilation croisée :

ARCH = arm
CROSS_COMPILE = arm-none-linux-gnueabihf-

Dans le fichier Makefile.sdk situé au niveau supérieur, spécifiez l'arbre de périphériques cible :

DEVICE_TREE ?= stm32mp157a-custom

4. Ajustements du code source pour le déploiement

Pour autoriser le flashage via USB OTG sans restriction, il est parfois nécessaire de modifier board/st/stm32mp1/stm32mp1.c en commentant les lignes forçant certains modes de démarrage spécifiques (comme BOOT_FASTBOOT ou BOOT_STM32PROG).

Créez un script nommé build_uboot.sh pour automatiser le processus :

#!/bin/bash
make stm32mp15_custom_defconfig
cp .config ../build-output/
make distclean
make -f $PWD/../Makefile.sdk all UBOOT_CONFIGS=stm32mp15_custom_defconfig,trusted,u-boot.stm32

5. Adaptation des périphériques : ADC et Ethernet

Désactivation de l'ADC

Le firwmare officiel tente parfois de vérifier le courant d'entrée via l'ADC. Si votre circuit d'alimentation diffère, cela peut bloquer le démarrage. Désactivez l'ADC via make menuconfig :

  • Désélectionner : Command line interface > Device access commands > adc
  • Désélectionner : Device Drivers > Enable ADC drivers

Configuraton du contrôleur Ethernet (PHY AR8031)

Si vous utilisez un contrôleur PHY Atheros AR8031, des registres spécifiques doivent être configurés dans drivers/net/phy/phy.c au sein de la fonction phy_probe pour stabiliser le lien et activer l'horloge 125 MHz :

/* Configuration spécifique AR8031 */
u16 reg_val;
phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x0003);
phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x805d);
phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4003);

reg_val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
phy_write(phydev, MDIO_DEVAD_NONE, 0xe, reg_val & ~(1 << 8)); /* Désactivation SmartEEE */

/* Activation sortie CLK 125MHz */
phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x0007);
phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
reg_val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
phy_write(phydev, MDIO_DEVAD_NONE, 0xe, (reg_val & 0xffe3) | 0x0018);

6. Support de l'eMMC et démarrage final

Pour activer le stockage eMMC sur l'interface SDMMC2, ajoutez le nœud suivant dans votre fichier .dtsi :

&sdmmc2 {
    pinctrl-names = "default", "opendrain", "sleep";
    pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>;
    non-removable;
    no-sd;
    no-sdio;
    bus-width = <8>;
    vmmc-supply = <&v3v3>;
    vqmmc-supply = <&vdd>;
    status = "okay";
};

Une fois compilé et flashé, vous pouvez définir les variables d'environnement dans la console U-Boot pour charger le noyau Linux depuis l'eMMC (périphérique 1) :

setenv bootargs 'console=ttySTM0,115200 root=/dev/mmcblk1p3 rootwait rw'
setenv bootcmd 'ext4load mmc 1:2 0xc2000000 uImage; ext4load mmc 1:2 0xc4000000 custom.dtb; bootm 0xc2000000 - 0xc4000000'
saveenv
reset

Étiquettes: STM32MP157 u-boot embedded-linux device-tree Bootloader

Publié le 31 juillet à 20h11