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]
The 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 in OpenSTLinux BSP:
- fsbl1 = TF-A BL2
- fbsl2 = TF-A BL2: second copy (a manual update is not needed by default, only used for fail-safe update)
- metadata1 = TF-A firmware update data : select FIP-A
- metadata2 = TF-A firmware update data : select FIP-A, second copy of the same binary
- fip-a = FIP, first slot
- fip-b = FIP, second slot, not required as the first slot is selected in metadata
- u-boot-env = U-Boot environment
See Boot_chain_overview for the bootloader definitions.
1.1. On a Linux® console with the Linux® dd command[edit source]
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 must 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 BSP.
You can 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=metadata.bin of=/dev/mmcblk0p3 conv=fdatasync dd if=metadata.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 must 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=metadata.bin of=/dev/sda3 conv=fdatasync dd if=metadata.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 used also to directly write file previously loaded in memory by other U-boot command.
For example, 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]
The 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 fail-safe update)
- Other binaries are in the GPT partitions of the e•MMC user area
- metadata1 = TF-A firmware update data : select FIP-A
- metadata2 = TF-A firmware update data : select FIP-A, second copy of the same binary
- fip-a = FIP, first slot
- fip-b = FIP, second slot, not required as the first slot is selected in metadata
- u-boot-env = U-Boot environment
The user must 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 could need to allow access, for example with:
echo 0 > /sys/class/block/mmcblk1boot0/force_ro
The mmc
tools allow the boot partition that can be selected [2].
The ROM code requires:
- <send_ack> =1 to enable the boot acknowledge bit in the e•MMC ext_csd register
- 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=metadata.bin of=/dev/mmcblk1p1 conv=fdatasync dd if=metadata.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.
You can 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 right e•MMC 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 (the boot acknowledge bit in the e•MMC ext_csd register 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
Do not change the last parameter partition_access value if you do not manually access 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 must be verified on your PC.
boot partitions
This boot partition by ROM code is selected in previous step #select boot partition, only the selected on needed to be updated.
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; but it not needed by default if boot1 is selected: mmc partconf 1 1 1 0
.
It is only required for fail-safe update, when the boot partition is selected after update with mmc partconf
.
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
And select boot2 partition after update:
mmc partconf 1 1 2 0
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=metadata.bin of=/dev/sda1 conv=fdatasync dd if=metadata.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 used also to directly write file previously loaded in memory by an other U-Boot command.
For example, to check the GPT partition of e•MMC, on dev=1 for STMicroelectronics board:
mmc dev 1 mmc part
To write TF-A , loaded at 0xC000000 at blk# = 0 for boot1 for 256KB (0x200*512):
mmc partconf 1 1 1 1 mmc write 0xC0000000 0 200 mmc partconf 1 1 1 0
See in #select boot partition for details on boot_partition=1 and partition_access=1 and 0 of mmc partconf
.
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.
3. Update of NOR[edit source]
The user has access to the NOR device partitions on target, with Linux® console or U-Boot console.
The 7 first partitions on the NOR device are by default in OpenSTLinux BSP:
- fsbl1 = TF-A BL2
- fbsl2 = TF-A BL2: second copy (a manual update is not needed by default, only used for fail-safe update)
- metadata1 = TF-A firmware update data : select FIP-A
- metadata2 = TF-A firmware update data : select FIP-A, second copy of the same binary
- fip-a = FIP, first slot
- fip-b = FIP, second slot, not required as the first slot is selected in metadata
- u-boot-env = U-Boot environment
3.1. On a Linux® console with the Linux® dd command[edit source]
3.2. On a U-Boot console[edit source]
NOR device partition can be listed using the command mtd list :
mtd list List of MTD devices: * nor1 - device: flash@0 - parent: spi@40430000 - driver: jedec_spi_nor - path: /soc@0/ommanager@40500000/spi@40430000/flash@0 - type: NOR flash - block size: 0x10000 bytes - min I/O: 0x1 bytes - 0x000000000000-0x000004000000 : "nor1" - 0x000000000000-0x000000040000 : "fsbla1" - 0x000000040000-0x000000080000 : "fsbla2" - 0x000000080000-0x0000000c0000 : "metadata1" - 0x0000000c0000-0x000000100000 : "metadata2" - 0x000000100000-0x000000500000 : "fip-a" - 0x000000500000-0x000000900000 : "fip-b" - 0x000000900000-0x000000980000 : "u-boot-env" - 0x000000980000-0x000004000000 : "nor-user"
In this example, "fip-a" partition is located on nor1 device, starts at offset 0x000000100000 and ends at offset 0x000000500000, its size is 0x40000. Before writing the fip-a partition, it must be erased. To erase "fip-a" partition located on nor1 which start at 0x000000100000 with size of 0x40000
mtd erase nor1 0x000000100000 0x40000
4. References[edit source]
Please refer to the following links for additional information: