This page explains how to manually update the bootloaders binary (including U-Boot and TF-A) on an SD card or on the e•MMC.
1. Update of SD card[edit source]
User has access to the SD card device partitions:
- on a Linux PC, with a card reader of this PC
- on target, with Linux console or U-Boot console.
The 7 first GPT partitions on the SD card are by default:
- FSBL1 = TF-A BL2
- FSBL2 = TF-A BL2
- metadata1 (select FIP-A)
- metadata2 (select FIP-A, second copy)
- FIP-A
- FIP-B (not required as FIP-A is selected)
- u-boot-env
See Boot_chain_overview for the bootloader definitions.
1.1. On a Linux console with the Linux dd command[edit source]
You can use the Linux dd
command to copy the bootloader files directly to the correct partition:
dd if=<file> of=/dev/<dev> conv=fdatasync
<dev> is:
- mmcblk<X>p<n>: PC-embedded card reader case or target Linux console
- sd<X><n>: USB-connected SD card reader case
where <X> is the ID of the device, and <n> the ID of the partition.
Note: the dd option conv=fdatasync is used to force synchronous copying.
The U-Boot environment is saved in the partition, named "u-boot-env": ID = 7 in OpenSTLinux; Erase this partition to clear this environment; for example, by using the previous dd command this input file: if=/dev/zero.
1.1.1. SD card update example[edit source]
When SD card device is mmcblk0, the GPT partition p<n> is /dev/mmcblk0p<n> (for example in OpenSTLinux target console or for a PC internal card reader):
dd if=tf-a-sdcard.stm32 of=/dev/mmcblk0p1 conv=fdatasync dd if=tf-a-sdcard.stm32 of=/dev/mmcblk0p2 conv=fdatasync dd if=metadata1.bin of=/dev/mmcblk0p3 conv=fdatasync dd if=metadata2.bin of=/dev/mmcblk0p4 conv=fdatasync dd if=fip.bin of=/dev/mmcblk0p5 conv=fdatasync dd if=/dev/zero of=/dev/mmcblk0p7 conv=fdatasync
1.2. On a U-Boot console[edit source]
1.2.1. With ums command[edit source]
Alternatively, with U-Boot ums
command, on mmc dev = 0 (SD card device on STMicroelectronics board), GPT partition <n> is /dev/sda<n> :
ums 0 mmc 0
The exported SD card is mounted on the Linux PC as a block device named sd<X> and the GPT partitions are exported by sd<X><n> where:
- <X> is the ID of the device starting at a
- <n> the ID of the partition.
If the block device SD card is available in /dev/sda (with <X> = a but this value need to be verified on your PC), the partitions are updated with the dd command:
dd if=tf-a-sdcard.stm32 of=/dev/sda1 conv=fdatasync dd if=tf-a-sdcard.stm32 of=/dev/sda{HighlightParam|2}} conv=fdatasync dd if=metadata1.bin of=/dev/sda3 conv=fdatasync dd if=metadata2.bin of=/dev/sda4 conv=fdatasync dd if=fip.bin of=/dev/sda5 conv=fdatasync dd if=/dev/zero of=/dev/sda7 conv=fdatasync
1.2.2. With mmc command[edit source]
The command mmc
can be use also to directly write file previously loaded in memory
The command mmc
can be use also
help mmc mmc - MMC sub system Usage: mmc info - display info of the current MMC device mmc read addr blk# ctn mmc write addr blk# cnt mmc erase blk# cnt mmc rescan [mode] mmc part - lists available partition on current mmc device mmc dev [dev] [part] [mode] - show or set current mmc device [partition] and set mode - the required speed mode is passed as the index from the following list [MMC_LEGACY, MMC_HS, SD_HS, MMC_HS_52, MMC_DDR_52, UHS_SDR12, UHS_SDR25, UHS_SDR50, UHS_DDR50, UHS_SDR104, MMC_HS_200, MMC_HS_400, MMC_HS_400_ES] mmc list - lists available devices ...
mmc dev 0 mmc part mmc write 0xC0000000 {{Highlight|22} 200
With block address (blk#) and clock count (ctn), multiple of block size = LBA of 512 bytes.
2. Update of e•MMC[edit source]
User has access to the e•MMC device partitions on target, with Linux console or U-Boot console.
The e•MMC memory mapping are by default:
- FSBL = TF-A is saved in the e•MMC boot partition
- Other binaries are in the GPT partitions of the e•MMC user area
- metadata1 (select FIP-A)
- metadata2 (select FIP-A, second copy)
- FIP-A
- FIP-B (not required as FIP-A is selected)
- u-boot-env
The user needs to select the e•MMC hardware partition to update: user data, boot1, or boot2.
2.1. On a Linux console with the Linux dd command[edit source]
If dev = mmcblk1 for e•MMC device (default on STMicroelectronics board)
The boot partitions are available in /dev/mmcblk1boot0 and /dev/mmcblk1boot1 [1].
The user perhaps needs to allow access, for example with:
echo 0 > /sys/class/block/mmcblk1boot0/force_ro
The mmc tools allow the boot partition to be selected [2].
The ROM code requires:
- <send_ack> =1
- the eMMC boot configuration is: 1 wire configuration and 25 MHz, it is done with the command:
mmc bootbus set single_backward x1 x1 dev/mmcblk1
To update TF-A in boot1 and select this boot partition (default):
dd if=tf-a-emmc.stm32 of=/dev/mmcblk1boot0 conv=fdatasync mmc bootpart enable 1 1 /dev/mmcblk1
To update TF-A in boot2 and select this boot partition (not needed by default, only required for fail-safe update):
dd if=tf-a-emmc.stm32 of=/dev/mmcblk1boot1 conv=fdatasync mmc bootpart enable 2 1 /dev/mmcblk1
To update the GPT partitions:
dd if=/dev/zero of=/dev/mmcblk1p1 conv=fdatasync dd if=metadata1.bin of=/dev/mmcblk1p1 conv=fdatasync dd if=metadata2.bin of=/dev/mmcblk1p2 conv=fdatasync dd if=fip.bin of=/dev/mmcblk1p3 conv=fdatasync
The U-Boot environment is saved in the partition, named "u-boot-env": ID = 5 in OpenSTLinux; Erase this partition to clear this environment; for example, by using the dd command this input file: if=/dev/zero.
dd if=/dev/zero of=/dev/mmcblk1p5 conv=fdatasync
See also [3].
2.2. On a U-Boot console[edit source]
If mmc device [dev] = 1 for e•MMC device in U-Boot (default on STMicroelectronics board).
The command mmc
is used in U-Boot console
help mmc
mmc - MMC sub system Usage: mmc info - display info of the current MMC device mmc read addr blk# cnt mmc write addr blk# cnt mmc erase blk# cnt mmc rescan [mode] mmc part - lists available partition on current mmc device mmc dev [dev] [part] [mode] - show or set current mmc device [partition] and set mode - the required speed mode is passed as the index from the following list [MMC_LEGACY, MMC_HS, SD_HS, MMC_HS_52, MMC_DDR_52, UHS_SDR12, UHS_SDR25, UHS_SDR50, UHS_DDR50, UHS_SDR104, MMC_HS_200, MMC_HS_400, MMC_HS_400_ES] mmc list - lists available devices mmc wp - power on write protect boot partitions mmc hwpartition <USER> <GP> <MODE> - does hardware partitioning arguments (sizes in 512-byte blocks): USER - <user> <enh> <start> <cnt> <wrrel> <{on|off}> : sets user data area attributes GP - <{gp1|gp2|gp3|gp4}> <cnt> <enh> <wrrel> <{on|off}> : general purpose partition MODE - <{check|set|complete}> : mode, complete set partitioning completed WARNING: Partitioning is a write-once setting once it is set to complete. Power cycling is required to initialize partitions after set to complete. mmc bootbus <dev> <boot_bus_width> <reset_boot_bus_width> <boot_mode> - Set the BOOT_BUS_WIDTH field of the specified device mmc bootpart-resize <dev> <boot part size MB> <RPMB part size MB> - Change sizes of boot and RPMB partitions of specified device mmc partconf <dev> [[varname] | [<boot_ack> <boot_partition> <partition_access>]] - Show or change the bits of the PARTITION_CONFIG field of the specified device If showing the bits, optionally store the boot_partition field into varname ...
Before the first boot, select the e•MMC correct boot configuration (1 wire, 25 MHz) with the command:
mmc bootbus 1 0 0 0
2.2.1. select boot partition[edit source]
The targeted e•MMC HW partition is selected in U-Boot by the command mmc partconf
:
For example:
* dev = 1 (e•MMC device on STMicroelectronics board) * boot_ack=1 (Boot Acknowledge is needed by ROM code) * boot_partition = 1 (Boot partition 1 enabled for boot) * partition_access = 0 (user data partition - default)
The command to select the boot partition used by ROM code on e•MMC at next reboot is:
- for boot1:
mmc partconf 1 1 1 0
- for boot2:
mmc partconf 1 1 2 0
- 0: user data partition (default)
- 1: boot partition 1
- 2: boot partition 2
Don't change the last parameter partition_access value if you don't manually access to the boot partition content with mmc read
or mmc write
:
2.2.2. With ums command[edit source]
The e•MMC update is done with the ums
command, with the U-Boot's partition syntax[4]:
<command> <interface> [devnum][.hwpartnum][:partnum|#partname]
The exported e•MMC is mounted on the Linux PC as a block device named sd<X> and the GPT partitions are exported by sd<X><n> where
- <X> is the ID of the device starting at a
- <n> the ID of the partition.
In the next examples we assume <X> = a, so the block device e•MMC available in /dev/sda but this value need to be verified on your PC.
boot partitions
To update FSBL=TF-A in the boot1 HW partition.
ums 0 mmc 1.1 UMS: LUN 0, dev 1, hwpart 1, sector 0x0, count 0x1000
On boot partitions, without GPT partitions, just copy TF-A binary on the block device /dev/sda exported by U-Boot.
dd if=tf-a-emmc.stm32 of=/dev/sda conv=fdatasync
For boot2, change the mmc device to 1.2.
user data partition
To export all the e•MMC in /dev/sda, including all GPT partitions in /dev/sdaN:
ums 0 mmc 1
And copy each binary in the GPT partitions of this block device:
dd if=metadata1.bin of=/dev/sda1 conv=fdatasync dd if=metadata2.bin of=/dev/sda2conv=fdatasync dd if=fip.bin of=/dev/sda3 conv=fdatasync
And clear the U-Boot environment with
dd if=/dev/zero of=/dev/mmcblk1p5 conv=fdatasync
2.2.3. With mmc command[edit source]
The command mmc
can be use also to directly write file previously loaded in memory
mmc dev 1 mmc part mmc write 0xC0000000 {{Highlight|0} 200
With block address (blk#) and clock count (ctn), multiple of block size = LBA of 512 bytes.
2.3. References[edit source]
Please refer to the following links for additional information: