flash manuale
On this page
Adesso puntiamo al flashare quello che abbiamo realizzato finora e vediamo se almeno qualcosa funziona. Apriamo quindi un progetto yocto, attiviamo il nostro layer e proviamo a buildare i recipe singolarmente, quindi:
bitbake u-boot
bitbake optee-os
bitbake trusted-firmware-aUno dei primi problemi è quello del COMPATIBLE_MACHINE. Yocto ci permette di definire per quali machine il nostro recipe (o .bbappend) ha senso di essere utilizzato. COMPATIBLE_MACHINE è una regex e per rendere la nostra machine compatibile ci basta usare:
COMPATIBLE_MACHINE:append = "|stm32mp257f-dk"Dopo aver risolto eventuali problemi nella build, i file che ci interessano sono:
- TFA
tmp/work/stm32mp257f_dk-poky-linux/trusted-firmware-a/2.10-stm32mp/image/firmware/tf-a-stm32mp257f-dk.stm32 - FIP
tmp/work/stm32mp257f_dk-poky-linux/trusted-firmware-a/2.10-stm32mp/image/firmware/fip.bin
Il layer meta-stm32mp2 che abbiamo realizzato finora è disponibile qui.
Adesso passiamo alla parte divertente. Per flashare la scheda esistono due modi principali:
- sdcard
- seriale
In entrambi i casi ci scontriamo con delle regole “hard-coded” definite dal ROM CODE, solitamente riguardo alla posizione e altre caratteristiche delle partizioni da cui viene caricato il bootloader.
Oltre al come flashare, dobbiamo anche decidere dove la scheda troverà i file necessari al boot. In sostanza dobbiamo decidere la tipologia di memoria flash che vogliamo utilizzare (sdcard, emmc, nand, nor, …)
Per informare il ROM code di quale processo
vogliamo utilizzare per flash e boot,
utilizziamo i boot switches della scheda:
docs
Per il momento faremo il boot da scard, ma vediamo come flashare la scheda sia tramite sdcard, sia tramite seriale.
flash da sdcard
Se la sdcard contiene una Global Positioning Table (GPT),
il ROM code cerca le prime 2 partizioni che iniziano il proprio nome
con fsbla oppure fsblm.
Se non trova la GPT, il ROM code cerca in delle posizioni fisse:
LBA0per FSBL-M1LBA640per FSBL-M2LBA1152per FSBL-A1LBA1664per FSBL-A2
dove LBA indica Logical Block Addressing, quindi
il numero di settore.
La dicitura fsbla, fsblm indica da quale core effettuare il boot,
qundi core A35, core M33.
La dicitura fsbla1, fsbla2 si riferisce invece alla eventuale ridondanza.
Utilizziamo il seguente script per formattare la sdcard utilizzando una GPT:
23# demonstrate the sdcard flashing for stm32mp2
24#
25# minimal working setup to access uboot console
26
27set -euo pipefail
28
29DEVICE="${1:-}"
30TFA="${2:-}"
31FIP="${3:-}"
32
33# Verify all 3 positional arguments are provided
34if [[ -z "$DEVICE" || -z "$TFA" || -z "$FIP" ]]; then
35 echo "Error: Missing required arguments." >&2
36 usage
37fi
38
39
40# FORMAT DEVICE
41sudo sgdisk --zap-all "$DEVICE"
42
43# ROM CODE REQUIREMENTS
44# TFA partition:
45# LABEL "fsbla" (first stage bootloader A35)
46# TYPE CODE GUID = 8DA63339-0007-60C0-C436-083AC8230908
47#
48# FIP partition
49# TYPE CODE GUID = 19D5DF83-11B0-457b-BE2C-7559C13142A5
50
51# sgdisk arguments
52# -n --new=partnum:start:end
53# -A (--attributes)
54# -c (--change-name)
55# -t (--typecode)
56# -u (--partition-guid)
57
58# TFA PARTITION
59sudo sgdisk \
60 -n 1:0:+512K \
61 -c 1:fsbla \
62 -t 1:8DA63339-0007-60C0-C436-083AC8230908 \
63 -u 1:R \
64 -p "$DEVICE"
65
66# FIP
67sudo sgdisk \
68 -n 2:0:+4M \
69 -c 2:fip \
70 -t 2:19d5df83-11b0-457b-be2c-7559c13142a5 \
71 -u 2:R \
72 -p "$DEVICE"
73
74# TFA CONTENTS
75sudo dd \
76 if=$TFA \
77 of=${DEVICE}1 \
78 bs=1M conv=fdatasync status=progress
79
80# FIP CONTENTS
81sudo dd \
82 if=$FIP \
83 of=${DEVICE}2 \
84 bs=1M conv=fdatasync status=progressAdesso cambiamo i boot switches della scheda e usiamo il valore 1000
per informare il ROM code che vogliamo fare il boot del core A35
tramite sdcard.
flash da seriale
Il processo si basa sul protocollo
USB DFU (Universal Serial Bus Device Firmware Upgrade),
quindi abbiamo ampia scelta sui tool da utilizzare.
Per comodità scegliamo di usare il tool da terminale
STM32CubeProgrammer,
in quanto implementa altre funzionalità
specifiche per stm32mp2.
L’installazione è descritta nella
documentazione ST.
Per ulteriore comodità, al momento useremo un container per installare il tool.
La parte principale per l’uso del cube programmer
è il file flashlayout.tsv
che definisce quali partizioni creare
e quali file flasharci dentro.
La sintassi di questo file è descritta nella
documentazione ST.
Per ottenere un risultato analogo al metodo precedente usiamo questo flashlayout:
#opt PhaseId Partition Type Device Offset Binary
- 0x01 fsbl-boot Binary none 0x00000000 tf-a-stm32mp257f-dk.stm32
- 0x02 fip-ddr FIP none 0x00000000 fip-ddr.bin
- 0x03 fip-boot FIP none 0x00000000 fip.bin
PD 0x04 fsbla Binary mmc0 0x00004400 tf-a-stm32mp257f-dk.stm32
PD 0x05 fip FIP mmc0 0x00104400 fip.binUn po’ di spiegazioni. La prima riga è commentata e indica solo i nomi dei campi.
Opt indica l’operazione da eseguire sulla partizione e può essere:
-per nessuna operazionePper sovrascrivere (update)PEper nessuna operazione (empty update)PDper formattare e sovrascrivere (delete and update)PDEper eliminare e lasciare vuota (delete and keep empty)
Name indica il nome della partizione e valgono le solite regole
Type è un enum associato al typecode GUID della partizione
e al momento ci interessa sapere che:
Binaryper GUID8DA63339-0007-60C0-C436-083AC8230908FIPper GUID19D5DF83-11B0-457b-BE2C-7559C13142A5FWU_MDATAper GUID8A7A84A0-8387-40F6-AB41-A8B9A5A60D23
PhaseId è un codice che identifica la tipologia di partizione
e anche il loro ordine. Per il bootloader esistono dei casi particolari:
0x01per TFA0x02per il file di training DDR0x03per FIP0xF*per comandi speciali
Device è un parametro che verrà utilizzato da UBOOT
per capire su che dispositivo flashare la partizione:
nonededicato per caricare bootloadermmcNindica l’istanza N di un mmc (mmc0=sdcard, mmc1=emmc)
Offset indica offset in byte all’interno della memoria flash,
ma permette anche dei valori speciali:
boot1per prima area boot della emccboot2per seconda area boot della emcc
Binary indica il path relativo al file da flashare
Il file flashlayout definisce le partizioni che troveremo sulla memoria flash,
ma anche delle partizioni dedicate al bootloader utilizzato per effettuare
le operazioni di scrittura sulla flash.
Questo è pressochè equivalente a quello che risiederà in flash,
ma non è un vincolo che sia il medesimo.
Per queste partizioni è necessario usare:
Opt=-PhaseIddedicatoType=BinaryDevice=noneOffset=0x0
Per poter essere eseguito anche da seriale,
è necessario definire il simbolo STM32MP_USB_PROGRAMMER=1
nella compilazione del TFA,
quindi nel recipe aggiungiamo:
19EXTRA_OEMAKE:append = " STM32MP_USB_PROGRAMMER=1 "Insomma è un grande insieme di regole arbitrarie, ma utili.
Adesso flashiamo, quindi…
Cambiamo i boot switches della scheda e usiamo il valore 0000
per fare un boot da seriale, permettendoci di
usare il micro per flashare un’altra memoria.
Per flashare, da una generica cartella dir del tipo:
workdir
├── tf-a-stm32mp257f-dk.stm32
├── fip.bin
└── flashlayout.tsvcerchiamo la scheda tra i dispositivi collegati:
STM32_Programmer_CLI -l usbeseguiamo il comando:
STM32_Programmer_CLI -c port=usb1 -w risultato finale
Collegandoci alla scheda tramite la porta seriale e riavviandola dovremmo vedere:
NOTICE: CPU: STM32MP257FAK Rev.Y
NOTICE: Model: STMicroelectronics STM32MP257F-DK Discovery Board
NOTICE: Board: MB1605 Var1.0 Rev.C-01
NOTICE: BL2: v2.10-stm32mp2-r2.0(release):v2.10-stm32mp-r2-dirty(cadc66f1)
NOTICE: BL2: Built : 09:19:57, Jun 2 2025
NOTICE: BL2: Booting BL31
NOTICE: BL31: v2.10-stm32mp2-r2.0(release):v2.10-stm32mp-r2-dirty(cadc66f1)
NOTICE: BL31: Built : 09:19:57, Jun 2 2025
I/TC: Early console on UART#2
I/TC:
I/TC: Embedded DTB found
I/TC: OP-TEE version: 4.0.0-stm32mp-r2 (gcc version 13.4.0 (GCC)) #1 Thu May 4
I/TC: WARNING: This OP-TEE configuration might be insecure!
I/TC: WARNING: Please check https://optee.readthedocs.io/en/latest/architectul
I/TC: Primary CPU initializing
I/TC: WARNING: All debug access are allowed
I/TC: Override the OTP 124: 0 to 0x18db6
I/TC: WARNING: Embeds insecure stm32mp_provisioning driver
I/TC: PMIC STPMIC REFID:2.@ V1.1
I/TC: Platform stm32mp2: flavor PLATFORM_FLAVOR - DT stm32mp257f-dk.dts
I/TC: OP-TEE ST profile: system_services
[ 0.000000] SCP-firmware 2.13.0-intree-optee-os-4.0.0-stm32mp-r2
[ 0.000000]
[ 0.000000] [FWK] Module initialization complete!
I/TC: Primary CPU switching to normal world boot
I/TC: Reserved shared memory is disabled
I/TC: Dynamic shared memory is enabled
I/TC: Normal World virtualization support is disabled
I/TC: Asynchronous notifications are enabled
U-Boot 2023.10-stm32mp-r2-rc8 (Jun 03 2025 - 07:35:36 +0000)
CPU: STM32MP257FAK Rev.Y
Model: STMicroelectronics STM32MP257F-DK Discovery Board
Board: stm32mp2 (st,stm32mp257f-dk)
Board: MB1605 Var1.0 Rev.C-01
DRAM: 4 GiB
optee optee: OP-TEE: revision 4.0 (a8dd87d4)
I/TC: Reserved shared memory is disabled
I/TC: Dynamic shared memory is enabled
I/TC: Normal World virtualization support is disabled
I/TC: Asynchronous notifications are enabled
Core: 419 devices, 42 uclasses, devicetree: board
WDT: Started watchdog with servicing every 1000ms (32s timeout)
NAND: 0 MiB
MMC: STM32 SD/MMC: 0, STM32 SD/MMC: 1
Loading Environment from MMC... OK
In: serial
Out: serial
Err: serial
Net: eth0: eth1@482c0000
FWU metadata read failed
No EFI system partition
No EFI system partition
Failed to persist EFI variables
Hit any key to stop autoboot: 0
Boot over mmc0!
switch to partitions #0, OK
mmc0 is current device E capiteremo dentro la console di uboot, dove potremo usare vari comandi:
STM32MP> version
U-Boot 2023.10-stm32mp-r2-rc8 (Jun 03 2025 - 07:35:36 +0000)
aarch64-poky-linux-gcc (GCC) 13.4.0
GNU ld (GNU Binutils) 2.42.0.20240723
STM32MP> mmc list
STM32 SD/MMC: 0 (SD)
STM32 SD/MMC: 1 (eMMC)Divertente no?