How to manually update bootloaders

Revision as of 19:52, 4 March 2022 by Registered User (→‎On a U-Boot console)
Applicable for STM32MP13x lines, STM32MP15x lines

This page explains how to manually update the bootloaders binary (including U-Boot and TF-A) on an SD card or on the eMMC.

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:

  1. FSBL1 = TF-A BL2
  2. FSBL2 = TF-A BL2
  3. metadata1 (select FIP-A)
  4. metadata2 (select FIP-A, second copy)
  5. FIP-A
  6. FIP-B (not required as FIP-A is selected)
  7. 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.

To clear this environment, erase the U-Boot partition before any update; for example, by writing 0 to this partition:

   dd if=/dev/zero of=/dev/mmcblk<X>p7 conv=fdatasync
   dd if=/dev/zero of=sd<X>7 conv=fdatasync

1.1.1. SD card update example[edit source]

The internal card reader is /dev/mmcblk0 or for a target Linux console, GPT partition <n> is /dev/mmcblk0p<n>:

  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 SD card is exported as the USB mass storage devices, 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/sda{{HighlightParam|5 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 eMMC[edit source]

User has access to the 'eMMC 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 eMMC boot partition
  • Other binaries are in the GPT partitions of the eMMC user area
  1. metadata1 (select FIP-A)
  2. metadata2 (select FIP-A, second copy)
  3. FIP-A
  4. FIP-B (not required as FIP-A is selected)
  5. u-boot-env

The user needs to select the eMMC 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 eMMC 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
  dd if=/dev/zero of=/dev/mmcblk1p7 conv=fdatasync

See also [3].

2.2. On a U-Boot console[edit source]

If mmc device = 1 for eMMC device in U-Boot (default on STMicroelectronics board).

Before the first boot, select the eMMC 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 eMMC HW partition is selected in U-Boot by the command mmc partconf:

   help mmc 
 ...
 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 [boot_ack boot_partition partition_access]
- Show or change the bits of the PARTITION_CONFIG field of the specified device

For example:

* dev = 1 (eMMC 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 eMMC 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 eMMC update is done with the ums command, with the U-Boot's partition syntax[4]:

 <command> <interface> [devnum][.hwpartnum][:partnum|#partname]

The exported eMMC 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 and <n> the ID of the partition. In the next example we assume <X> = a, so the block device eMMC 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 eMMC in /dev/sda, including all GPT partitions in /dev/sdaN:

  ums 0 mmc 1
  dd if=fip.bin of=/dev/sda1 conv=fdatasync

And copy the FIP binary in the first partition of this block device:

You can also export only the first GPT partition ("fip" partition index is 1) in /dev/sda:

  ums 0 mmc 1:1 
  dd if=fip.bin of=/dev/sda 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

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 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: