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 (second copy, manual update not needed by default, only needed for fail-safe automatic update)
- 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.
The dd
command need to be repeated for each GPT partition to update.
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 dd
command this input file: if=/dev/zero.
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), the update of the SD card is done with:
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,the SD card device on STMicroelectronics board:
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/sda2 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 by other U-boot command.
help mmc
To check partition offset on dev 0, SD Card on STMicroelectonics boards:
mmc dev 0
mmc part
Partition Map for MMC device 0 -- Partition Type: EFI
Part Start LBA End LBA Name Attributes Type GUID Partition GUID 1 0x00000022 0x00000221 "fsbl1" ....
To write TF-A, loaded at 0xC000000 at blk# = 22 for 256KB (0x200*512)
mmc write 0xC0000000 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 partitions (2 copy for failsafe update)
- 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[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 for e•MMC device configuration.
mmc bootbus <dev> <boot_bus_width> <reset_boot_bus_width> <boot_mode>
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
:
mmc partconf <dev> [[varname] | [<boot_ack> <boot_partition> <partition_access>]]
With:
* 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
- 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
.
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 (not needed by default, only required for fail-safe update):
mmc partconf 1 1 2 0
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 U-Boot's partition syntax:
<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
To update boot2, change the mmc device to 1.2 (not needed by default, only required for fail-safe update).
ums 0 mmc 1.2 UMS: LUN 0, dev 1, hwpart 2, sector 0x0, count 0x1000 dd if=tf-a-emmc.stm32 of=/dev/sda conv=fdatasync
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/sda2 conv=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 by other U-boot command.
To check the GPT partition of e•MMC, on dev=1 for STMicroelectronics board:
mmc dev 1 mmc part
To write metadata1, loaded at 0xC000000 at blk# = 0x00, size = 1KB (0x2*512)
mmc write 0xC0000000 00 2
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: