Difference between revisions of "How to manually update bootloaders"

[checked revision] [quality revision]
m
m
 

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 To update an SD card with the Linux dd command[edit]

When a Linux console has access to the SD card device partitions:

  • on a Linux PC
    • with a card reader of this PC
    • through a USB connection to the target and the ums command executed on a U-Boot console
  • on target, with Linux console.

The 3 first GPT partitions on the SD card are:

  1. FSBL1
  2. FSBL2
  3. FIP

See Boot_chain_overview for the bootloader definitions.

You can use the Linux dd command to copy the FSBL and SSBL 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.

1.1 U-Boot environment[edit]

The U-Boot environment is saved at the end of the U-Boot partition, named "fip": ID = 3.

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>p3 conv=fdatasync
 
  dd if=/dev/zero of=sd<X>3 conv=fdatasync

1.2 SD card update example[edit]

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=/dev/zero of=/dev/mmcblk0p3 conv=fdatasync
  dd if=fip.bin of=/dev/mmcblk0p3 conv=fdatasync

Alternatively, with U-Boot console, dev = 0 (SD card device on ST Microelectronics board), GPT partition <n> is /dev/sda<n>:

 
 mmc dev 0 
  ums 0 mmc 0
 
  dd if=tf-a-sdcard.stm32 of=/dev/sda1 conv=fdatasync
  dd if=tf-a-sdcard.stm32 of=/dev/sda2 conv=fdatasync
  dd if=/dev/zero of=/dev/sda3 conv=fdatasync
  dd if=fip.bin of=/dev/sda3 conv=fdatasync

1.3 SD card update example with SPL as FSBL[edit]

The USB card reader is /dev/sdb, GPT partition <n> is /dev/sdb<n>:

 
 dd if=u-boot-spl.stm32 of=/dev/sdb1 conv=fdatasync
  dd if=u-boot-spl.stm32 of=/dev/sdb2 conv=fdatasync
  dd if=/dev/zero of=/dev/sdb3 conv=fdatasync
  dd if=u-boot.img of=/dev/sdb3 conv=fdatasync

2 Update of e•MMC with the Linux dd command[edit]

The same command, dd, can be used to update e•MMC memory mapping:

  • SSBL U-Boot is the first GPT partition in the e•MMC user area
  • FSBL = TF-A (or SPL) is saved at the beginning of the e•MMC boot partition

The user needs to select the e•MMC hardware partition to update: user data, boot1, or boot2.

2.1 On a Linux console[edit]

If dev = mmcblk1 for e•MMC device (default on ST Microelectronics 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 STM32MP15x 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:

 
 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:

 
 dd if=tf-a-emmc.stm32 of=/dev/mmcblk1boot1 conv=fdatasync
  mmc bootpart enable 2 1 /dev/mmcblk1

To update U-Boot in the first GPT partition:

 
 dd if=/dev/zero of=/dev/mmcblk1p1 conv=fdatasync
  dd if=fip.bin of=/dev/mmcblk1p1 conv=fdatasync

See also [3].

2.2 On a U-Boot console[edit]

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 mmc partconf[edit]

The targeted e•MMC 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 (e•MMC device on ST Microelectronics 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

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:

  • 0: user data partition (default)
  • 1: boot partition 1
  • 2: boot partition 2

2.2.2 ums[edit]

The e•MMC update is done with the ums command, with the U-Boot's partition syntax[4]:

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

For example, the The exported e•MMC block device 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 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 the FIP binary in the first partition of this block device availalbe in /dev/sda1:

 
 dd if=fip.bin of=/dev/sda1 conv=fdatasync

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

3 References[edit]

Please refer to the following links for additional information:


This page explains how to manually update the bootloaders binary (including [[U-Boot_overview|U-Boot]] and [[TF-A_overview|TF-A]]) on an SD card or on the ''e''•MMC.

== To update an SD card with the Linux dd command ==

When a Linux console has access to the SD card device partitions:
* on a Linux PC
** with a card reader of this PC
** through a USB connection to the target and the  [[How to use USB mass storage in U-Boot|<code>ums</code> command]] executed on a U-Boot console
* on target, with Linux console.

[[STM32MP15_Flash_mapping#SD_card_memory_mapping|The 3 first GPT partitions on the SD card]] are:
# FSBL1
# FSBL2
# FIP

See [[Boot_chain_overview]] for the bootloader definitions.

You can use the Linux <code>dd</code> command to copy the FSBL and SSBL directly to the correct partition:
  {{PC$}}  dd if={{HighlightParam|<file>}} of=/dev/{{HighlightParam|<dev>}} conv={{HighlightParam|fdatasync}}

{{HighlightParam|<dev>}} is:
* mmcblk{{Highlight|<X>}}p{{Highlight|<n>}}: PC-embedded card reader case or target Linux console
* sd{{Highlight|<X>}}{{Highlight|<n>}}: USB-connected SD card reader case
where {{Highlight|<X>}} is the ID of the device, and {{Highlight|<n>}} the ID of the partition.

Note: the dd option {{HighlightParam|conv}}={{HighlightParam|fdatasync}} is used to force synchronous copying.

=== U-Boot environment ===

The U-Boot environment is saved at the end of the U-Boot partition, named "fip":  ID  = {{HighlightParam|3}}.

To clear this environment, erase the U-Boot partition before any update; for example, by writing 0 to this partition:
  {{PC$}}  dd if=/dev/zero of=/dev/mmcblk{{Highlight|<X>}}p{{HighlightParam|3}} conv=fdatasync

  {{PC$}}  dd if=/dev/zero of=sd{{Highlight|<X>}}{{HighlightParam|3}} conv=fdatasync

=== SD card update example ===
The internal card reader is /dev/mmcblk0 or for a target Linux console, GPT partition <n> is {{HighlightParam|/dev/mmcblk0}}p<n>:
  {{PC$}} dd if={{HighlightParam|tf-a-sdcard.stm32}} of={{HighlightParam|/dev/mmcblk0}}p1 conv=fdatasync
  {{PC$}} dd if={{HighlightParam|tf-a-sdcard.stm32}} of={{HighlightParam|/dev/mmcblk0}}p2 conv=fdatasync
  {{PC$}} dd if=/dev/zero of={{HighlightParam|/dev/mmcblk0}}p3 conv=fdatasync
  {{PC$}} dd if={{HighlightParam|fip.bin}} of={{HighlightParam|/dev/mmcblk0}}p3 conv=fdatasync

Alternatively, with U-Boot console, dev = {{Highlight|0}} (SD card device on ST Microelectronics board), GPT partition <n> is {{HighlightParam|/dev/sda}}<n>:
  {{Board$}} mmc dev {{Highlight|0}} 
  {{Board$}} ums 0 mmc {{Highlight|0}}

  {{PC$}} dd if={{HighlightParam|tf-a-sdcard.stm32}} of={{HighlightParam|/dev/sda}}1 conv=fdatasync
  {{PC$}} dd if={{HighlightParam|tf-a-sdcard.stm32}} of={{HighlightParam|/dev/sda}}2 conv=fdatasync
  {{PC$}} dd if=/dev/zero of={{HighlightParam|/dev/sda}}3 conv=fdatasync
  {{PC$}} dd if={{HighlightParam|fip.bin}} of={{HighlightParam|/dev/sda}}3 conv=fdatasync

=== SD card update example with SPL as FSBL ===
The USB card reader is /dev/sdb, GPT partition <n> is {{HighlightParam|/dev/sdb<n>}}:
  {{PC$}} dd if={{HighlightParam|u-boot-spl.stm32}} of={{HighlightParam|/dev/sdb1}} conv=fdatasync
  {{PC$}} dd if={{HighlightParam|u-boot-spl.stm32}} of={{HighlightParam|/dev/sdb2}} conv=fdatasync
  {{PC$}} dd if=/dev/zero of={{HighlightParam|/dev/sdb3}} conv=fdatasync
  {{PC$}} dd if={{HighlightParam|u-boot.img}} of={{HighlightParam|/dev/sdb3}} conv=fdatasync

== Update of ''e''•MMC with the Linux dd command ==

The same command, <code>dd</code>, can be used to update [[STM32MP15_Flash_mapping#eMMC_memory_mapping|''e''•MMC memory mapping]]:
* SSBL U-Boot is the first GPT partition in the ''e''•MMC user area
* FSBL = TF-A (or SPL) is saved at the beginning of the ''e''•MMC boot partition

The user needs to select the ''e''•MMC hardware partition to update: user data, boot1, or boot2.

=== On a Linux console ===

If dev = {{Highlight|mmcblk1}}  for ''e''•MMC device (default on ST Microelectronics board)

The boot partitions are available in  /dev/{{Highlight|mmcblk1}}{{HighlightParam|boot0}} and  /dev/{{Highlight|mmcblk1}}{{HighlightParam|boot1}} <ref>https://www.kernel.org/doc/Documentation/mmc/mmc-dev-parts.txt</ref>.

The user perhaps needs to allow access, for example with:
  {{Board$}}  echo 0 > /sys/class/block/{{Highlight|mmcblk1}}{{HighlightParam|boot0}}/force_ro

The mmc tools allow the boot partition to be selected <ref>https://manpages.debian.org/buster/mmc-utils/mmc.1.en.html</ref>.

The STM32MP15x ROM code requires:
* <send_ack> =1
* the eMMC boot configuration is: 1 wire configuration and 25 MHz, it is done with the command:
  {{Board$}}  mmc bootbus set  single_backward x1 x1 dev/{{Highlight|mmcblk1}}

To update TF-A in boot1 and select this boot partition:   
  {{Board$}} dd if={{HighlightParam|tf-a-emmc.stm32}} of=/dev/{{Highlight|mmcblk1}}{{HighlightParam|boot0}} conv=fdatasync
  {{Board$}} mmc bootpart enable {{HighlightParam|1}} 1 /dev/{{Highlight|mmcblk1}}

To update TF-A in boot2 and select this boot partition:  
  {{Board$}} dd if={{HighlightParam|tf-a-emmc.stm32}} of=/dev/{{Highlight|mmcblk1}}{{HighlightParam|boot1}} conv=fdatasync
  {{Board$}} mmc bootpart enable {{HighlightParam|2}} 1 /dev/{{Highlight|mmcblk1}}

To update U-Boot in the first GPT partition:
  {{Board$}} dd if=/dev/zero of=/dev/{{Highlight|mmcblk1}}{{HighlightParam|p1}} conv=fdatasync
  {{Board$}} dd if={{HighlightParam|fip.bin}} of=/dev/{{Highlight|mmcblk1}}{{HighlightParam|p1}} conv=fdatasync

See also <ref>https://www.emcraft.com/som/stm32mp1/booting-linux-from-emmc</ref>.

=== On a U-Boot console ===

Before the first boot, select the ''e''•MMC correct boot configuration (1 wire, 25 MHz) with the command:
  {{Board$}} mmc bootbus {{HighlightParam|1}} 0 0 0

==== mmc partconf ====
The targeted ''e''•MMC HW partition is selected in U-Boot by the command <code>mmc partconf</code>:

  {{Board$}}  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 {{HighlightParam|partition_access}}]
 - Show or change the bits of the PARTITION_CONFIG field of the specified device

For example:
 * dev = {{Highlight|1}} (''e''•MMC device on ST Microelectronics board)
 * boot_ack=1 (Boot Acknowledge is needed by ROM code) 
 * boot_partition = {{HighlightParam|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 {{Highlight|boot1}}:
  {{Board$}} mmc partconf {{Highlight|1}} 1 {{HighlightParam|1}} 0
* for {{Highlight|boot2}}:
  {{Board$}} mmc partconf {{Highlight|1}} 1 {{HighlightParam|2}} 0

Don't change the last parameter {{HighlightParam|partition_access}} value if you don't manually access to the boot partition content with <code>mmc read</code> or <code>mmc write</code>:
* {{HighlightParam|0}}: user data partition (default)
* {{HighlightParam|1}}: boot partition 1
* {{HighlightParam|2}}: boot partition 2

==== ums  ====
The ''e''•MMC update is done with the [[How to use USB mass storage in U-Boot|<code>ums</code> command]], with the U-Boot's partition syntax<ref>https://u-boot.readthedocs.io/en/latest/usage/partitions.html</ref>:<command> <interface> [devnum][.hwpartnum][:partnum|#partname]
For example, the The exported ''e''•MMC block device is mounted on the Linux PC as {{HighlightParam|/dev/sda}}a block device named sd{{Highlight|<X>}} and the GPT partitions are exported by sd{{Highlight|<X>}}{{Highlight|<n>}} where {{Highlight|<X>}} is the ID of the device starting at '''a''' and {{Highlight|<n>}} the ID of the partition.

In the next example we assume {{Highlight|<X>}} = '''a''', so the block device ''e''•MMC available in {{HighlightParam|/dev/sda}} but this value need to be verified on your PC.

'''boot partitions'''

To update FSBL=TF-A in the {{HighlightParam|boot1}} HW partition.
  {{Board$}} ums 0 mmc {{Highlight|1}}.{{HighlightParam|1}}
  UMS: LUN 0, dev {{Highlight|1}}, hwpart {{HighlightParam|1}}, sector 0x0, count 0x1000

On boot partitions, without GPT partitions, just copy TF-A binary on the block device {{HighlightParam|/dev/sda}} exported by U-Boot.
  {{PC$}} dd if=tf-a-emmc.stm32 of={{HighlightParam|/dev/sda}}  conv=fdatasync

For {{HighlightParam|boot2}}, change the mmc device to {{Highlight|1}}.{{HighlightParam|2}}.

'''user data partition'''

To export all the  ''e''•MMC  in {{HighlightParam|/dev/sda}}, including all GPT partitions in {{HighlightParam|/dev/sda}}N:
  {{Board$}} ums 0 mmc {{Highlight|1}}

And copy the FIP binary in the first partition of this block device availalbe in {{HighlightParam|/dev/sda}}{{Highlight|1}}:
  {{PC$}} dd if={{HighlightParam|fip.bin}} of={{HighlightParam|/dev/sda}}{{Highlight|1}} conv=fdatasync

You can also export only the first GPT partition ("fip" partition index is {{Highlight|1}}) in {{HighlightParam|/dev/sda}}:
  {{Board$}} ums 0 mmc {{Highlight|1}}:{{Highlight|1}} 
  {{PC$}} dd if={{HighlightParam|fip.bin}} of={{HighlightParam|/dev/sda}} conv=fdatasync

==References==
Please refer to the following links for additional information:
<references />

<noinclude>

[[Category:How to populate boards]]
{{PublicationRequestId | 16075 | 2020-05-12}}</noinclude>
Line 134: Line 134:
 
   <command> <interface> [devnum][.hwpartnum][:partnum|#partname]
 
   <command> <interface> [devnum][.hwpartnum][:partnum|#partname]
   
For example, the exported ''e''•MMC block device is mounted on the PC as {{HighlightParam|/dev/sda}}.
+
The exported ''e''•MMC is mounted on the Linux PC as a block device named sd{{Highlight|<X>}} and the GPT partitions are exported by sd{{Highlight|<X>}}{{Highlight|<n>}} where {{Highlight|<X>}} is the ID of the device starting at '''a''' and {{Highlight|<n>}} the ID of the partition.
  +
 
  +
In the next example we assume {{Highlight|<X>}} = '''a''', so the block device ''e''•MMC available in {{HighlightParam|/dev/sda}} but this value need to be verified on your PC.
   
 
'''boot partitions'''
 
'''boot partitions'''
Line 152: Line 154:
 
   {{Board$}} ums 0 mmc {{Highlight|1}}
 
   {{Board$}} ums 0 mmc {{Highlight|1}}
   
And copy the FIP binary in the first partition of block device availalbe in {{HighlightParam|/dev/sda}}{{Highlight|1}}:
+
And copy the FIP binary in the first partition of this block device:
 
   {{PC$}} dd if={{HighlightParam|fip.bin}} of={{HighlightParam|/dev/sda}}{{Highlight|1}} conv=fdatasync
 
   {{PC$}} dd if={{HighlightParam|fip.bin}} of={{HighlightParam|/dev/sda}}{{Highlight|1}} conv=fdatasync