Difference between revisions of "U-Boot overview"

[quality revision] [quality revision]
m
m
 

1 Das U-Boot[edit]

Das U-Boot ("the Universal Boot Loader" or U-Boot) is an open-source bootloader that can be used on ST boards to initialize the platform and load the Linux® kernel.

U-Boot Logo.png

Read the README file before starting using U-Boot. It covers the following topics:

  • source file tree structure
  • description of CONFIG defines
  • instructions for building U-Boot
  • brief description of the Hush shell
  • list of common environment variables

Do go further, read the documentations available in doc/ and the documentation generated by make htmldocs [1].

2 U-Boot overview[edit]

Zoom out to STM32MPU Embedded Software

The STM32 MPU boot chain uses Trusted Firmware-A (TF-A) as FSBL and U-Boot as SSBL.

The same U-Boot source can also generate an alternate FSBL named SPL. The boot chain becomes: SPL as FSBL and U-Boot as SSBL.

Warning.png This alternate boot chain with SPL cannot be used for product development.


2.1 SPL: alternate FSBL[edit]

2.1.1 SPL description[edit]

The U-Boot SPL or SPL is an alternate first stage bootloader (FSBL).
It is a small binary (bootstrap utility) generated from the U-Boot source and stored in the internal limited-size embedded RAM. SPL main features are the following:

  • It is loaded by the ROM code.
  • It performs the initial CPU and board configuration (clocks and DDR memory).
  • It loads the SSBL (U-Boot) into the DDR memory.

2.1.2 SPL restrictions[edit]

Warning.png SPL cannot be used for product development.

SPL is provided only as an example of the simplest FSBL with the objective to support upstream U-Boot development. However, several known limitations have been identified when SPL is used in conjunction with the minimal secure monitor provided within U-Boot for basic boot chain. These limitations apply to:

  • power management
  • secure access to registers
  • limited features (STM32CubeProgrammer / boot from NAND Flash memory)
  • SCMI support for clock and reset (not compatible with latest Linux kernel device tree)

There is no workaround for these limitations.

2.1.3 SPL execution sequence[edit]

SPL executes the following main steps in SYSRAM:

  • board_init_f(): driver initialization including DDR initialization (mininimal stack and heap: CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN)
  • configuration of heap in DDR memory (CONFIG_SPL_SYS_MALLOC_F_LEN)
  • board_init_r(): initialization of the other drivers activated in the SPL device tree
  • loading and execution of U-Boot (or Kernel in Falcon mode[2]: README.falcon ).

2.2 U-Boot: SSBL[edit]

2.2.1 U-Boot description[edit]

U-Boot is the second-stage bootloader (SSBL) of boot chain for STM32 MPU platforms.

SSBL main features are the following:

  • It is configurable and expendable.
  • It features a simple command line interface (CLI), allowing users to interact over a serial port console.
  • It provides scripting capabilities.
  • It loads the kernel into RAM and gives control to the kernel.
  • It manages several internal and external devices such as NAND and NOR Flash memories, Ethernet and USB.
  • It supports the following features and commands:
    • File systems: FAT, UBI/UBIFS, JFFS
    • IP stack: FTP
    • Display: LCD, HDMI, BMP for splashcreen
    • USB: host (mass storage) or device (DFU stack)

2.2.2 U-Boot execution sequence[edit]

U-Boot executes the following main steps in DDR memory:

  • Pre-relocation initialization (common/board_f.c): minimal initialization (such as CPU, clock, reset, DDR and console) running at the CONFIG_SYS_TEXT_BASE load address.
  • Relocation: copy of the code to the end of DDR memory.
  • Post-relocation initialization:(common/board_r.c): initialization of all the drivers.
  • Command execution through autoboot (CONFIG_AUTOBOOT) or console shell.
    • Execution of the boot command (by default bootcmd=CONFIG_BOOTCOMMAND):
      for example, execution of the command bootm to:
      • load and check images (such as kernel, device tree and ramdisk)
      • fixup the kernel device tree
      • install the secure monitor (optional) or
      • pass the control to the Linux kernel (or to another target application)

3 U-Boot configuration[edit]

The U-Boot binary configuration is based on

  • Kbuild infrastructure (as in Linux Kernel, you can use make menuconfig in U-Boot)
    The configurations are based on:
  • other compilation flags defined in include/configs/stm32mp*.h (these flags are progressively migrated to Kconfig)
    The file name is configured through CONFIG_SYS_CONFIG_NAME.
    For STM32MP15x lines More info.png, the include/configs/stm32mp1.h file is used.
  • DeviceTree: U-Boot binaries include a device tree blob that is parsed at runtime

All the configuration flags (prefixed by CONFIG_) are described in the source code, either in the README file or in the documentation directory .
For example, CONFIG_SPL activates the SPL compilation.
Hence to compile U-Boot, select the <target> and the device tree for the board in order to choose a predefined configuration.
Refer to #U-Boot_build for examples.

3.1 Kbuild[edit]

Like the kernel, the U-Boot build system is based on configuration symbols (defined in Kconfig files). The selected values are stored in a .config file located in the build directory, with the same makefile target. .
Proceed as follows:

  • Select a predefined configuration (defconfig file in configs directory ) and generate the first .config:
 
PC $> make <config>_defconfig.
  • Change the U-Boot compile configuration (modify .config) by using one of the following five make commands:
 
PC $> make menuconfig --> menu based program
 PC $> make config  --> line-oriented configuration
 PC $> make xconfig --> QT program[3]
 PC $> make gconfig --> GTK program
 PC $> make nconfig --> ncurse menu based program

You can then compile U-Boot with the updated .config.

Warning: the modification is performed locally in the build directory. It will be lost after a make distclean.

Save your configuration to be able to use it as a defconfig file:

  
PC $> make savedefconfig

This target saves the current config as a defconfig file in the build directory. It can then be compared with the predefined configuration (configs/stm32mp*defconfig).

The other makefile targets are the following:

  
PC $> make help
 ....
 Configuration targets:
   config	  - Update current config utilising a line-oriented program
   nconfig         - Update current config utilising a ncurses menu based
                     program
   menuconfig	  - Update current config utilising a menu based program
   xconfig	  - Update current config utilising a Qt based front-end
   gconfig	  - Update current config utilising a GTK+ based front-end
   oldconfig	  - Update current config utilising a provided .config as base
   localmodconfig  - Update current config disabling modules not loaded
   localyesconfig  - Update current config converting local mods to core
   defconfig	  - New config with default from ARCH supplied defconfig
   savedefconfig   - Save current config as ./defconfig (minimal config)
   allnoconfig	  - New config where all options are answered with no
   allyesconfig	  - New config where all options are accepted with yes
   allmodconfig	  - New config selecting modules when possible
   alldefconfig    - New config with all symbols set to default
   randconfig	  - New config with random answer to all options
   listnewconfig   - List new options
   olddefconfig	  - Same as oldconfig but sets new symbols to their
                    default value without prompting

3.2 Device tree[edit]

Refer to doc/README.fdt-control for details.

The board device tree has the same binding as the kernel. It is integrated within the U-Boot binaries: u-boot.bin

  • By default, it is appended at the end of the code (CONFIG_OF_SEPARATE).
  • It can be embedded in the U-Boot binary (CONFIG_OF_EMBED). This is particularly useful for debugging since it enables easy .elf file loading.

The U-Boot device tree (u-boot.dtb) can be also provided as external file loaded by FSBL when U-Boot code is started (u-boot-nodtb.bin: code without device tree): device tree address is provided as boot parameter (in r2 register).

A default device tree is available in the defconfig file (by setting CONFIG_DEFAULT_DEVICE_TREE).

You can either select another supported device tree using the DEVICE_TREE make flag. For stm32mp boards, the corresponding file is <dts-file-name>.dts in arch/arm/dts/stm32mp*.dts , with <dts-file-name> set to the full name of the board:

  
PC $> make DEVICE_TREE=<dts-file-name>

or provide a device tree blob (dtb file) resulting from the dts file compilation, by using the EXT_DTB option:

  
PC $> make EXT_DTB=boot/<dts-file-name>.dtb

The SPL device tree is also generated from this device tree. However to reduce its size, the U-Boot makefile uses the fdtgrep tool to parse the full U-Boot DTB and identify all the drivers required by SPL.

To do this, U-Boot uses specific device-tree flags to determine if the associated driver is initialized prior to U-Boot relocation and/or if the associated node is present in SPL :

  • u-boot,dm-pre-reloc => present in SPL, initialized before relocation in U-Boot
  • u-boot,dm-pre-proper => initialized before relocation in U-Boot
  • u-boot,dm-spl => present in SPL

In the device tree used by U-Boot, these flags need to be added in all the nodes used in SPL or in U-Boot before relocation, and for all used handles (clock, reset, pincontrol).

To obtain a device tree file <dts-file-name>.dts that is identical to the Linux kernel one, these U-Boot properties are only added for ST boards in the add-on file <dts-file-name>-u-boot.dtsi. This file is automatically included in <dts-file-name>.dts during device tree compilation (this is a generic U-Boot Makefile behavior).

4 U-Boot command line interface (CLI)[edit]

Refer to U-Boot Command Line Interface.

If CONFIG_AUTOBOOT is activated, you have CONFIG_BOOTDELAY seconds (2s by default, 1s for ST configuration) to enter the console by pressing any key, after the line below is displayed and bootcmd is executed (CONFIG_BOOTCOMMAND):

 Hit any key to stop autoboot:  2

4.1 Commands[edit]

The commands are defined in cmd/*.c . They are activated through the corresponding CONFIG_CMD_* configuration flag.

Use the help command in the U-Boot shell to list the commands available on your device:

 
Board $> help

Below the list of all commands extracted from U-Boot Manual (not-exhaustive):

  • Information Commands
    • bdinfo - prints Board Info structure
    • coninfo - prints console devices and information
    • flinfo - prints Flash memory information
    • iminfo - prints header information for application image
    • help - prints online help
  • Memory Commands
    • base - prints or sets the address offset
    • crc32 - checksum calculation
    • cmp - memory compare
    • cp - memory copy
    • md - memory display
    • mm - memory modify (auto-incrementing)
    • mtest - simple RAM test
    • mw - memory write (fill)
    • nm - memory modify (constant address)
    • loop - infinite loop on address range
  • Flash Memory Commands
    • cp - memory copy
    • flinfo - prints Flash memory information
    • erase - erases Flash memory
    • protect - enables or disables Flash memory write protection
    • mtdparts - defines a Linux compatible MTD partition scheme
  • Execution Control Commands
    • source - runs a script from memory
    • bootm - boots application image from memory
    • go - starts application at address 'addr'
  • Download Commands
    • bootp - boots image via network using BOOTP/TFTP protocol
    • dhcp - invokes DHCP client to obtain IP/boot params
    • loadb - loads binary file over serial line (kermit mode)
    • loads - loads S-Record file over serial line
    • rarpboot- boots image via network using RARP/TFTP protocol
    • tftpboot- boots image via network using TFTP protocol
  • Environment Variables Commands
    • printenv- prints environment variables
    • saveenv - saves environment variables to persistent storage
    • setenv - sets environment variables
    • run - runs commands in an environment variable
    • bootd - default boot, that is run 'bootcmd'
  • Flattened Device Tree support
    • fdt addr - selects the FDT to work on
    • fdt list - prints one level
    • fdt print - recursive printing
    • fdt mknode - creates new nodes
    • fdt set - sets node properties
    • fdt rm - removes nodes or properties
    • fdt move - moves FDT blob to new address
    • fdt chosen - fixup dynamic information
  • Special Commands
    • i2c - I2C sub-system
  • Storage devices
  • Miscellaneous Commands
    • echo - echoes args to console
    • reset - performs a CPU reset
    • sleep - delays the execution for a predefined time
    • version - prints the monitor version

To add a new command, refer to doc/README.commands .

4.2 U-Boot environment variables[edit]

The U-Boot behavior is configured through environment variables.

Refer to Manual and README / Environment Variables.

On the first boot, U-Boot uses a default environment embedded in the U-Boot binary. You can modify it by changing the content of CONFIG_EXTRA_ENV_SETTINGS in your configuration file (for example ./include/configs/stm32mp1.h) (see README / - Default Environment).

This environment can be modified and saved in the boot device. When it is present, it is loaded during U-Boot initialization:

  • To boot from e•MMC/SD card (CONFIG_ENV_IS_IN_MMC): at the end of the partition indicated by config field "u-boot,mmc-env-partition" in device-tree (for ST boards: partition named "ssbl" for ST boardsfip" in ecosystem release ≥ v3.0.0 More info.png with FIP support or partition named "ssbl" without FIP support).
  • To boot from NAND Flash memory (CONFIG_ENV_IS_IN_UBI): in the two UBI volumes "config" (CONFIG_ENV_UBI_VOLUME) and "config_r" (CONFIG_ENV_UBI_VOLUME_REDUND).
  • To boot from NOR Flash memory (CONFIG_ENV_IS_IN_SPI_FLASH): the u-boot_env mtd parttion (at offset CONFIG_ENV_OFFSET).

4.2.1 env command[edit]

The env command allows displaying, modifying and saving the environment in U-Boot console.

 
Board $> help env
 env - environment handling commands
 
 Usage:
 env default [-f] -a - [forcibly] reset default environment
 env default [-f] var [...] - [forcibly] reset variable(s) to their default values
 env delete [-f] var [...] - [forcibly] delete variable(s)
 env edit name - edit environment variable
 env exists name - tests for existence of variable
 env print [-a | name ...] - print environment
 env print -e [name ...] - print UEFI environment
 env run var [...] - run commands in an environment variable
 env save - save environment
 env set -e name [arg ...] - set UEFI variable; unset if 'arg' not specified
 env set [-f] name [arg ...]

Example: proceed as follows to restore the default environment and save it. This is useful after a U-Boot upgrade:

 
Board $> env default -a
 Board $> env save

You can also use the command activated by CONFIG_CMD_ERASEENV:

 
Board $> env erase

4.2.2 bootcmd[edit]

"bootcmd" variable is the autoboot command. It defines the command executed when U-Boot starts (CONFIG_BOOTCOMMAND).

For stm32mp, CONFIG_BOOTCOMMAND="run bootcmd_stm32mp":

 
Board $> env print bootcmd    
  bootcmd=run bootcmd_stm32mp

"bootcmd_stm32mp" is a script that selects the command to be executed for each boot device (see ./include/configs/stm32mp1.h), based on generic distro scripts:

  • To boot from a serial/usb device: execute the stm32prog command.
  • To boot from an e•MMC, SD card: boot only on the same device (bootcmd_mmc...).
  • To boot from a NAND Flash memory: boot on ubifs partition on the NAND memory (bootcmd_ubi0).
  • To boot from a NOR Flash memory: use the SD card (on SDMMC 0 on ST boards with bootcmd_mmc0)
 
Board $> env print bootcmd_stm32mp

You can then change this configuration:

  • either permanently in your board file
    • default environment by CONFIG_EXTRA_ENV_SETTINGS (see ./include/configs/stm32mp1.h)
    • change CONFIG_BOOTCOMMAND value in your defconfig
 CONFIG_BOOTCOMMAND="run bootcmd_mmc0"
 CONFIG_BOOTCOMMAND="run distro_bootcmd"
  • or temporarily in the saved environment:
 
Board $> env set bootcmd run bootcmd_mmc0 
 Board $> env save

Note: To reset the environment to its default value:

 
Board $> env default bootcmd
 Board $> env save

4.3 Generic Distro configuration[edit]

Refer to doc/README.distro for details.

This feature is activated by default on ST boards (CONFIG_DISTRO_DEFAULTS):

  • one boot command (bootmcd_xxx) exists for each bootable device.
  • U-Boot is independent from the Linux distribution used.
  • bootcmd is defined in ./include/config_distro_bootcmd.h

When DISTRO is enabled, the command that is executed by default is include/config_distro_bootcmd.h :

 bootcmd=run distro_bootcmd

This script tries any device found in the 'boot_targets' variable and executes the associated bootcmd.

Example for mmc0, mmc1, mmc2, pxe and ubifs devices:

 bootcmd_mmc0=setenv devnum 0; run mmc_boot
 bootcmd_mmc1=setenv devnum 1; run mmc_boot
 bootcmd_mmc2=setenv devnum 2; run mmc_boot
 bootcmd_pxe=run boot_net_usb_start; dhcp; if pxe get; then pxe boot; fi
 bootcmd_ubifs0=setenv devnum 0; run ubifs_boot

U-Boot searches for an extlinux.conf configuration file for each bootable device. This file defines the kernel configuration to be used with bootm command:

  • bootargs
  • files to start the OS:
    • kernel (uImage) + device tree + ramdisk files (optional)
    • FIT image, including all these needed files (for details see doc/uImage.FIT/howto.tx )

4.4 U-Boot scripting capabilities[edit]

"Script files" are command sequences that are executed by the U-Boot command interpreter. This feature is particularly useful to configure U-Boot to use a real shell (hush) as command interpreter.

See U-Boot script manual for an example.

5 U-Boot build[edit]

See U-Boot Documentation.

5.1 Prerequisites[edit]

  • a PC with Linux and tools:
  • U-Boot source code
    • the latest STMicroelectronics U-Boot version
      • tar.xz file from Developer Package (for example STM32MP1) or from latest release on ST github [4]
      • from GITHUB[5], with git command
 
PC $> git clone https://github.com/STMicroelectronics/u-boot

  • from the Mainline U-Boot in official GIT repository [6]
 
PC $> git clone https://source.denx.de/u-boot/u-boot.git

5.2 ARM cross compiler[edit]

A cross compiler [7] must be installed on your Host (X86_64, i686, ...) for the ARM targeted Device architecture. In addition, the $PATH and $CROSS_COMPILE environment variables must be configured in your shell.

You can use gcc for ARM, available in:

For example, to use gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf.tar.xz from arm, extract the toolchain in $HOME and update your environment with:

 
PC $> export PATH=$HOME/gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf/bin:$PATH
 PC $> export CROSS_COMPILE=arm-none-linux-gnueabihf-

For example, to use gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabi.tar.xz
from https://releases.linaro.org/components/toolchain/binaries/7.2-2017.11/arm-linux-gnueabi/
Unzip the toolchain in $HOME and update your environment with:

 
PC $> export PATH=$HOME/gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabi/bin:$PATH
 PC $> export CROSS_COMPILE=arm-linux-gnueabi-

5.3 Compilation[edit]

In the U-Boot source directory, select the defconfig for the <target> and the <device tree> for your board and then execute the make all command:

 
PC $> make <target>_defconfig
 PC $> make DEVICE_TREE=<device tree> all

Use help to list other targets than all:

 
PC $> make help
 

Optionally

  • KBUILD_OUTPUT can be used to change the output build directory in order to compile several targets in the source directory. For example:
 
PC $> export KBUILD_OUTPUT=<path>

  • DEVICE_TREE can also be exported to your environment when only one board is supported. For example:
 
PC $> export DEVICE_TREE=<device-tree>

The result is the following:

 
PC $> export KBUILD_OUTPUT=<path>
 PC $> export DEVICE_TREE=<device tree>
 PC $> make <target>_defconfig
 PC $> make all

Examples from STM32MP15 U-Boot:

The boot chain for STM32MP15x lines More info.png use stm32mp15_trusted_defconfig:

 
PC $> make stm32mp15_trusted_defconfig
 PC $> make DEVICE_TREE=stm32mp157f-dk2 all
 
PC $> export KBUILD_OUTPUT=../build/stm32mp15_trusted
 PC $> export DEVICE_TREE=stm32mp157c-ev1
 PC $> make stm32mp15_trusted_defconfig
 PC $> make all

5.4 Output files[edit]

The resulting U-Boot files are located in your build directory (U-Boot or KBUILD_OUTPUT).

Since ecosystem release v3.0.0 More info.png , two U-Boot files are used by ST boards to generate FIP used by FSBL TF-A, with or without OP-TEE support:

  • BL33_CFG=u-boot.dtb : the U-Boot device tree, selected by DEVICE_TREE, loaded by TF-A BL2 and amended by secure monitor (SPMIN or OP-TEE)
  • BL33=u-boot-nodtb.bin: the U-Boot executable, loaded by TF-A BL2 started by secure monitor with BL33_CFG as parameter

Nota: All the compiled device tree are available in $KBUILD_OUTPUT/arch/arm/dts/*.dtb.
You can select them as BL33_CFG without U-Boot recompilation.

See TF-A_overview for FIP details.

The file used to debug with gdb is

  • u-boot : elf file for U-Boot

For ecosystem release ≤ v2.1.0 : u-boot.stm32 : U-Boot binary with STM32 image header, including device tree selected by DEVICE_TREE, loaded by TF-A

This behavior can be restored if you activate CONFIG_STM32MP15x_STM32IMAGE in your defconfig of ecosystem release v3.0.0 More info.png

This temporary option is only introduced to facilitate the FIP migration but it will be removed in the next EcosystemRelease.

The STM32 image format (*.stm32) is managed by mkimage U-Boot tools and Signing_tool. It is requested by ROM code and TF-A without FIP support (see STM32 header for binary files for details).

6 References[edit]


== Das U-Boot ==
[https://en.wikipedia.org/wiki/Das_U-Boot Das U-Boot] ("the Universal Boot Loader" or U-Boot) is an open-source bootloader that can be used on ST boards to initialize the platform and load the Linux<sup>&reg;</sup> kernel.

[[File: U-Boot Logo.png|link=U-Boot logo|thumb|link=https://u-boot.readthedocs.io/en/stable/]]

* Official website: [https://www.denx.de/wiki/U-Boot https://www.denx.de/wiki/U-Boot]
* Official manual: [http://www.denx.de/wiki/U-Boot/Documentation U-Boot project documentation] and [https://www.denx.de/wiki/DULG/Manual https://www.denx.de/wiki/DULG/Manual]
* Official [https://www.denx.de/wiki/U-Boot/SourceCode '''source code'''] is available under [https://git-scm.com/ git] repository at [https://source.denx.de/u-boot/u-boot]

Read the {{CodeSource | U-Boot | README | README file}} before starting using U-Boot. It covers the following topics:
* source file tree structure
* description of CONFIG defines
* instructions for building U-Boot
* brief description of the Hush shell
* list of common environment variables

Do go further, read the documentations available in {{CodeSource | U-Boot | doc/}} and the documentation generated by <code>make htmldocs</code> <ref>https://u-boot.readthedocs.io/en/stable/index.html</ref>.

== U-Boot overview ==
[[File: STM32MPU Embedded Software architecture overview.png|link=STM32MPU Embedded Software architecture overview|thumb|Zoom out to STM32MPU Embedded Software]]

The [[Boot_chain_overview#STM32MP boot sequence|STM32 MPU boot chain]] uses [[TF-A overview|Trusted Firmware-A (TF-A)]] as FSBL and [[#U-Boot: SSBL|U-Boot as SSBL]].

The same U-Boot source can also generate an alternate FSBL named [[#SPL: alternate FSBL|SPL]]. The boot chain becomes: SPL as FSBL and U-Boot as SSBL.

{{Warning | This alternate [[Boot_chain_overview|boot chain]] with SPL cannot be used for product development.}} 
<br clear=all>
<div class="mw-collapsible mw-collapsed">

=== SPL: alternate FSBL ===<div class="mw-collapsible-content">


==== SPL description ====
The '''U-Boot SPL''' or '''SPL''' is an alternate first stage bootloader (FSBL).<br/>

It is a small binary (bootstrap utility) generated from the U-Boot source and stored in the internal limited-size embedded RAM. SPL main features are the following: 
* It is loaded by the ROM code.
* It performs the initial CPU and board configuration (clocks and DDR memory).
* It loads the SSBL (U-Boot) into the DDR memory.

==== SPL restrictions ====

{{Warning | SPL cannot be used for product development.}} 
SPL is provided only as an example of the simplest FSBL with the objective to support upstream U-Boot development. However, several known limitations have been identified when SPL is used in conjunction with the minimal secure monitor provided within U-Boot for basic boot chain. These limitations apply to:
* power management
* secure access to registers
* limited features (STM32CubeProgrammer / boot from NAND Flash memory)
* SCMI support for clock and reset (not compatible with latest Linux kernel device tree)

There is no workaround for these limitations.

==== SPL execution sequence====
'''SPL''' executes the following main steps in SYSRAM:
* '''board_init_f()''': driver initialization including DDR initialization (mininimal stack and heap: CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN)
* configuration of heap in DDR memory (CONFIG_SPL_SYS_MALLOC_F_LEN)
* '''board_init_r()''': initialization of the other drivers activated in the SPL device tree
* loading and execution of U-Boot (or Kernel in Falcon mode<ref>https://www.denx.de/wiki/pub/U-Boot/MiniSummitELCE2013/2013-ELCE-U-Boot-Falcon-Boot.pdf</ref>: {{CodeSource | U-Boot | doc/README.falcon | README.falcon }}).</div></div>


=== U-Boot: SSBL ===
==== U-Boot description ====
'''U-Boot''' is the second-stage bootloader (SSBL) of [[Boot_chain_overview#STM32MP boot sequence| boot chain]] for STM32 MPU platforms.

SSBL main features are the following: 
* It is configurable and expendable.
* It features a simple command line interface (CLI), allowing users to interact over a serial port console. 
* It provides scripting capabilities.
* It loads the kernel into RAM and gives control to the kernel.
* It manages several internal and external devices such as NAND and NOR Flash memories, Ethernet and USB.
* It supports the following features and commands:
** File systems: FAT, UBI/UBIFS, JFFS
** IP stack: FTP
** Display: LCD, HDMI, BMP for splashcreen
** USB: host (mass storage) or device (DFU stack)

==== U-Boot execution sequence ====
'''U-Boot''' executes the following main steps in DDR memory:
* '''Pre-relocation''' initialization (common/board_f.c): minimal initialization (such as CPU, clock, reset, DDR and console) running at the CONFIG_SYS_TEXT_BASE load address.
* '''Relocation''': copy of the code to the end of DDR memory.
* '''Post-relocation initialization''':(common/board_r.c): initialization of all the drivers.
* '''Command execution''' through autoboot (CONFIG_AUTOBOOT) or console shell.
** Execution of the boot command (by default [[#bootcmd|bootcmd=CONFIG_BOOTCOMMAND]]): <br/>for example, execution of the command <code>bootm</code> to: 
*** load and check images (such as kernel, device tree and ramdisk)
*** fixup the kernel device tree
*** install the secure monitor (optional) or 
*** pass the control to the Linux kernel (or to another target application)

== U-Boot configuration ==
The U-Boot binary configuration is based on 
* '''Kbuild infrastructure''' (as in [[Menuconfig_or_how_to_configure_kernel|Linux Kernel]], you can use <code>make menuconfig</code> in U-Boot)<br/>The configurations are based on:
** options defined in Kconfig files (CONFIG_ compilation flags)
** the selected configuration file: {{CodeSource | U-Boot | configs/ | configs/stm32mp*_defconfig}}<br/>

* '''other compilation flags''' defined in {{CodeSource | U-Boot | include/configs/ | include/configs/stm32mp*.h}}  (these flags are progressively migrated to Kconfig)<br/>The file name is configured through CONFIG_SYS_CONFIG_NAME.<br/>For  {{MicroprocessorDevice | device=15}}, the {{CodeSource | U-Boot | include/configs/stm32mp1.h | include/configs/stm32mp1.h}} file is used.

* '''[[Device_tree|DeviceTree]]''': U-Boot binaries include a device tree blob that is parsed at runtime
All the configuration flags (prefixed by CONFIG_) are described in the source code, either in the {{CodeSource | U-Boot | README | README}} file or in the {{CodeSource | U-Boot | doc/ | documentation directory}}.<br/>For example, CONFIG_SPL activates the SPL compilation.<br />

Hence to compile U-Boot, [[#Kbuild|select the <target>]] and [[#Device_tree|the device tree]] for the board in order to choose a predefined configuration.<br/>

Refer to [[#U-Boot_build]] for examples.

=== Kbuild ===

Like the kernel, the U-Boot build system is based on [[Menuconfig_or_how_to_configure_kernel|configuration symbols]] (defined in Kconfig files). The selected values are stored in a '''.config''' file located in the build directory, with the same makefile target. .<br/>

Proceed as follows:
* Select a predefined configuration (defconfig file in {{CodeSource | U-Boot | configs/ | configs directory }}) and generate the first '''.config''':
  {{PC$}} make <config>_defconfig.

* Change the U-Boot compile configuration (modify .config) by using one of the following  five <code>make</code> commands:
  {{PC$}} '''make menuconfig''' {{Highlight|--> menu based program}}
  {{PC$}} make config  {{Highlight|--> line-oriented configuration}}
  {{PC$}} make xconfig {{Highlight|--> QT program<ref>https://en.wikipedia.org/wiki/Xconfig</ref>}}
  {{PC$}} make gconfig {{Highlight|--> GTK program}}
  {{PC$}} make nconfig {{Highlight|--> ncurse menu based program}}
You can then compile U-Boot with the updated .config.

Warning: the modification is performed locally in the build directory. It will be lost after a <code>make distclean</code>.

Save your configuration to be able to use it as a defconfig file:
   {{PC$}} make savedefconfig
This target saves the current config as a defconfig file in the build directory. It can then be compared with the predefined configuration (configs/stm32mp*defconfig).

The other makefile targets are the following:

   {{PC$}} make help
  ....
  Configuration targets:
    config	  - Update current config utilising a line-oriented program
    nconfig         - Update current config utilising a ncurses menu based
                      program
    menuconfig	  - Update current config utilising a menu based program
    xconfig	  - Update current config utilising a Qt based front-end
    gconfig	  - Update current config utilising a GTK+ based front-end
    oldconfig	  - Update current config utilising a provided .config as base
    localmodconfig  - Update current config disabling modules not loaded
    localyesconfig  - Update current config converting local mods to core
    defconfig	  - New config with default from ARCH supplied defconfig
    savedefconfig   - Save current config as ./defconfig (minimal config)
    allnoconfig	  - New config where all options are answered with no
    allyesconfig	  - New config where all options are accepted with yes
    allmodconfig	  - New config selecting modules when possible
    alldefconfig    - New config with all symbols set to default
    randconfig	  - New config with random answer to all options
    listnewconfig   - List new options
    olddefconfig	  - Same as oldconfig but sets new symbols to their
                     default value without prompting

=== Device tree ===
Refer to {{CodeSource | U-Boot | doc/README.fdt-control | doc/README.fdt-control}} for details.

The board [[Device_tree|device tree ]] has the same binding as the kernel. It is integrated within the U-Boot binaries: [[U-Boot_overview#Output_files|u-boot.bin]]
* By default, it is appended at the end of the code  (CONFIG_OF_SEPARATE).
* It can be embedded in the U-Boot binary (CONFIG_OF_EMBED). This is particularly useful for debugging since it enables easy .elf file loading.

The U-Boot device tree ([[U-Boot_overview#Output_files|u-boot.dtb]]) can be also provided as external file loaded by FSBL when U-Boot code is started ([[U-Boot_overview#Output_files|u-boot-nodtb.bin]]: code without device tree): device tree address is provided as boot parameter (in r2 register).

A default device tree is available in the defconfig file (by setting CONFIG_DEFAULT_DEVICE_TREE).

You can either select another supported device tree using the DEVICE_TREE make flag. For stm32mp boards, the corresponding file is {{HighlightParam|<dts-file-name>}}.dts in {{CodeSource | U-Boot | arch/arm/dts/ | arch/arm/dts/stm32mp*.dts}}, with {{HighlightParam|<dts-file-name>}} set to the full name of the board:
   {{PC$}} make DEVICE_TREE={{HighlightParam|<dts-file-name>}}

or provide a device tree blob (dtb file) resulting from the dts file compilation, by using the EXT_DTB option:
   {{PC$}} make EXT_DTB={{HighlightParam|boot/<dts-file-name>.dtb}}

The SPL device tree is also generated from this device tree. However to reduce its size, the U-Boot makefile uses the fdtgrep tool to parse the full U-Boot DTB and identify all the drivers required by SPL.

To do this, U-Boot uses specific device-tree flags to determine if the associated driver is initialized prior to U-Boot relocation and/or if the associated node is present in SPL :
* '''u-boot,dm-pre-reloc''' => present in SPL, initialized before relocation in U-Boot
* '''u-boot,dm-pre-proper''' => initialized before relocation in U-Boot
* '''u-boot,dm-spl''' => present in SPL

In the device tree used by U-Boot, these flags '''need to be added in all the nodes''' used in SPL or in U-Boot before relocation, and for all used handles (clock, reset, pincontrol).

To obtain a device tree file '''{{HighlightParam|<dts-file-name>}}.dts''' that is identical to the Linux kernel one, these U-Boot properties are only added for ST boards in the add-on file '''{{HighlightParam|<dts-file-name>}}-u-boot.dtsi'''. This file is automatically included in '''{{HighlightParam|<dts-file-name>}}.dts''' during device tree compilation (this is a generic U-Boot Makefile behavior).

== U-Boot command line interface (CLI) ==
Refer to [http://www.denx.de/wiki/view/DULG/UBootCommandLineInterface U-Boot Command Line Interface].

If CONFIG_AUTOBOOT is activated, you have CONFIG_BOOTDELAY seconds (2s by default, 1s for ST configuration) to enter the console by pressing any key, after the line below is displayed and [[#bootcmd|bootcmd]] is executed (CONFIG_BOOTCOMMAND):
  Hit any key to stop autoboot:  2

=== Commands ===
The commands are defined in {{CodeSource | U-Boot | cmd/ | cmd/*.c}}. They are activated through the corresponding '''CONFIG_CMD_*''' configuration flag.

Use the <code>help</code> command in the U-Boot shell to list the commands available on your device:
  {{Board$}} help

Below the list of all commands extracted from [http://www.denx.de/wiki/view/DULG/Manual U-Boot Manual] ('''not-exhaustive'''):
* [http://www.denx.de/wiki/view/DULG/UBootCmdGroupInfo Information Commands]
** bdinfo - prints Board Info structure
** coninfo - prints console devices and information
** flinfo - prints Flash memory information
** iminfo - prints header information for application image
** help - prints online help
* [http://www.denx.de/wiki/view/DULG/UBootCmdGroupMemory Memory Commands]
** base - prints or sets the address offset
** crc32 - checksum calculation
** cmp - memory compare
** cp - memory copy
** md - memory display
** mm - memory modify (auto-incrementing)
** mtest - simple RAM test
** mw - memory write (fill)
** nm - memory modify (constant address)
** loop - infinite loop on address range
* [http://www.denx.de/wiki/view/DULG/UBootCmdGroupFlash Flash Memory Commands]
** cp - memory copy
** flinfo - prints Flash memory information
** erase - erases Flash memory
** protect - enables or disables Flash memory write protection
** mtdparts - defines a Linux compatible MTD partition scheme
* [http://www.denx.de/wiki/view/DULG/UBootCmdGroupExec Execution Control Commands]
** source - runs a script from memory
** bootm - boots application image from memory
** go - starts application at address 'addr'
* [http://www.denx.de/wiki/view/DULG/UBootCmdGroupDownload Download Commands]
** bootp - boots image via network using BOOTP/TFTP protocol
** dhcp - invokes DHCP client to obtain IP/boot params
** loadb - loads binary file over serial line (kermit mode)
** loads - loads S-Record file over serial line
** rarpboot- boots image via network using RARP/TFTP protocol
** tftpboot- boots image via network using TFTP protocol
* [http://www.denx.de/wiki/view/DULG/UBootCmdGroupEnvironment Environment Variables Commands]
** printenv- prints environment variables
** saveenv - saves environment variables to persistent storage
** setenv - sets environment variables
** run - runs commands in an environment variable
** bootd - default boot, that is run 'bootcmd'
* [http://www.denx.de/wiki/view/DULG/UBootCmdFDT Flattened Device Tree support]
** fdt addr - selects the FDT to work on
** fdt list - prints one level
** fdt print - recursive printing
** fdt mknode - creates new nodes
** fdt set - sets node properties
** fdt rm - removes nodes or properties
** fdt move - moves FDT blob to new address
** fdt chosen - fixup dynamic information
* [http://www.denx.de/wiki/view/DULG/UBootCmdGroupSpecial Special Commands]
** i2c - I2C sub-system
* [http://www.denx.de/wiki/view/DULG/UBootStorageDevices Storage devices]
* [http://www.denx.de/wiki/view/DULG/UBootCmdGroupMisc Miscellaneous Commands]
** echo - echoes args to console
** reset - performs a CPU reset  
** sleep - delays the execution for a predefined time 
** version - prints the monitor version

To add a new command, refer to {{CodeSource | U-Boot | doc/README.commands }}.

=== U-Boot environment variables ===

The U-Boot behavior is configured through environment variables.

Refer to [http://www.denx.de/wiki/view/DULG/UBootEnvVariables Manual] and {{CodeSource | U-Boot | README | README}} / Environment Variables.

On the first boot, U-Boot uses a default environment embedded in the U-Boot binary. You can modify it by changing the content of CONFIG_EXTRA_ENV_SETTINGS in your configuration file (for example ./include/configs/stm32mp1.h) (see {{CodeSource | U-Boot | README | README}} / - Default Environment).

This environment can be modified and saved in the boot device. When it is present, it is loaded during U-Boot initialization:
* To boot from ''e''•MMC/SD card (CONFIG_ENV_IS_IN_MMC): at the end of the partition indicated by config field "u-boot,mmc-env-partition" in device-tree (partition named "ssbl" for ST boardsfor ST boards: partition named "fip" in {{EcosystemRelease | revision=3.0.0 | range=and after}} with FIP support or partition named "ssbl" without FIP support).
* To boot from NAND Flash memory (CONFIG_ENV_IS_IN_UBI): in the two UBI volumes "config" (CONFIG_ENV_UBI_VOLUME) and "config_r"  (CONFIG_ENV_UBI_VOLUME_REDUND).
* To boot from NOR Flash memory (CONFIG_ENV_IS_IN_SPI_FLASH): the u-boot_env mtd parttion (at offset CONFIG_ENV_OFFSET).

==== env command ====

The <code>env</code> command allows displaying, modifying and saving the environment in U-Boot console.

  {{Board$}} help env
  env - environment handling commands

  Usage:
  env default [-f] -a - [forcibly] reset default environment
  env default [-f] var [...] - [forcibly] reset variable(s) to their default values
  env delete [-f] var [...] - [forcibly] delete variable(s)
  env edit name - edit environment variable
  env exists name - tests for existence of variable
  env print [-a | name ...] - print environment
  env print -e [name ...] - print UEFI environment
  env run var [...] - run commands in an environment variable
  env save - save environment
  env set -e name [arg ...] - set UEFI variable; unset if 'arg' not specified
  env set [-f] name [arg ...]

Example: proceed as follows to restore the default environment and save it. This is useful after a U-Boot upgrade:

  {{Board$}} env default -a
  {{Board$}} env save

You can also use the command activated by CONFIG_CMD_ERASEENV:

  {{Board$}} env erase

==== bootcmd ====
"bootcmd" variable is the autoboot command. It defines the command executed when U-Boot starts (CONFIG_BOOTCOMMAND).

For stm32mp,  CONFIG_BOOTCOMMAND="run bootcmd_stm32mp":

  {{Board$}} env print bootcmd    
   bootcmd=run bootcmd_stm32mp

"bootcmd_stm32mp" is a script that selects the command to be executed for each boot device (see ./include/configs/stm32mp1.h), based on [[#Generic Distro configuration|generic distro scripts]]:
* To boot from a serial/usb device: execute the <code>stm32prog</code> command.
* To boot from an ''e''•MMC, SD card: boot only on the same device (bootcmd_mmc...).
* To boot from a NAND Flash memory: boot on ubifs partition on the NAND memory (bootcmd_ubi0).
* To boot from a NOR Flash memory: use the SD card (on SDMMC 0 on ST boards with bootcmd_mmc0)

  {{Board$}} env print bootcmd_stm32mp

You can then change this configuration:
* either permanently in your board file
** default environment by CONFIG_EXTRA_ENV_SETTINGS (see ./include/configs/stm32mp1.h)
** change CONFIG_BOOTCOMMAND value in your defconfig

  CONFIG_BOOTCOMMAND="run bootcmd_mmc0"

  CONFIG_BOOTCOMMAND="run distro_bootcmd"

* or temporarily in the saved environment:

  {{Board$}} env set bootcmd run bootcmd_mmc0 
  {{Board$}} env save

Note: To reset the environment to its default value: 

  {{Board$}} env default bootcmd
  {{Board$}} env save

=== Generic Distro configuration ===

Refer to {{CodeSource | U-Boot | doc/README.distro | doc/README.distro}} for details.

This feature is activated by default on ST boards (CONFIG_DISTRO_DEFAULTS):
* one boot command (bootmcd_xxx) exists for each bootable device.
* U-Boot is independent from the Linux distribution used.
* bootcmd is defined in {{CodeSource | U-Boot | ./include/config_distro_bootcmd.h }}

When DISTRO is enabled, the command that is executed by default is {{CodeSource | U-Boot | include/config_distro_bootcmd.h}}:
  bootcmd=run distro_bootcmd

This script tries any device found in the 'boot_targets' variable and executes the associated bootcmd.

Example for mmc0, mmc1, mmc2, pxe and ubifs devices:
  bootcmd_mmc0=setenv devnum 0; run mmc_boot
  bootcmd_mmc1=setenv devnum 1; run mmc_boot
  bootcmd_mmc2=setenv devnum 2; run mmc_boot
  bootcmd_pxe=run boot_net_usb_start; dhcp; if pxe get; then pxe boot; fi
  bootcmd_ubifs0=setenv devnum 0; run ubifs_boot

U-Boot searches for an '''extlinux.conf''' configuration file for each bootable device. This file defines the kernel configuration to be used with <code>bootm</code> command: 
* bootargs
* files to start the OS:
**  kernel (uImage) + device tree + ramdisk files (optional)
** FIT image, including all these needed files (for details see {{CodeSource | U-Boot | doc/uImage.FIT/howto.tx}})

=== U-Boot scripting capabilities ===

"Script files" are command sequences that are executed by the U-Boot command interpreter. This feature is particularly useful to configure U-Boot to use a real shell (hush) as command interpreter.

See [http://www.denx.de/wiki/view/DULG/UBootScripts| U-Boot script manual] for an example.

== U-Boot build ==

See {{DocSource | domain=U-Boot | path=build/index.html|text=U-Boot Documentation}}.

=== Prerequisites ===

* a PC with Linux and tools: 
** see [[PC_prerequisites]]
** [[#ARM cross compiler]]
* U-Boot source code
** the latest STMicroelectronics U-Boot version
*** tar.xz file from Developer Package (for example [[STM32MP1_Developer_Package#Installing_the_U-Boot|STM32MP1]]) or from latest release on ST github <ref>https://github.com/STMicroelectronics/u-boot/releases</ref>

*** from GITHUB<ref>https://github.com/STMicroelectronics/u-boot</ref>, with <code>git</code> command
  {{PC$}} git clone https://github.com/STMicroelectronics/u-boot
:* from the Mainline U-Boot in official GIT repository <ref>https://source.denx.de/u-boot/u-boot.git or https://github.com/u-boot/u-boot</ref>

  {{PC$}} git clone https://source.denx.de/u-boot/u-boot.git

=== ARM cross compiler ===

A cross compiler <ref>https://en.wikipedia.org/wiki/Cross_compiler</ref> must be installed on your Host (X86_64, i686, ...) for the ARM targeted Device architecture. In addition, the $PATH and $CROSS_COMPILE environment variables must be configured in your shell.

You can use gcc for ARM, available in:
* the SDK toolchain (see [[Cross-compile with OpenSTLinux SDK]])<br/>PATH and CROSS_COMPILE are automatically updated.
* an existing package<br/>For example, install gcc-arm-linux-gnueabihf on Ubuntu/Debian: ({{PC$}} sudo apt-get.
* an existing toolchain:
** latest gcc toolchain provided by arm (https://developer.arm.com/open-source/gnu-toolchain/gnu-a/downloads/)
** gcc v7 toolchain provided by linaro: (https://www.linaro.org/downloads/)

For example, to use ''gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf.tar.xz'' from arm, extract the toolchain in $HOME and update your environment with:
  {{PC$}} export PATH=$HOME/gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf/bin:$PATH
  {{PC$}} export CROSS_COMPILE=arm-none-linux-gnueabihf-

For example, to use '''gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabi.tar.xz'''<br/>from https://releases.linaro.org/components/toolchain/binaries/7.2-2017.11/arm-linux-gnueabi/<br/>

Unzip the toolchain in $HOME and update your environment with:
  {{PC$}} export PATH=$HOME/gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabi/bin:$PATH
  {{PC$}} export CROSS_COMPILE=arm-linux-gnueabi-

=== Compilation  ===
In the U-Boot source directory, select the defconfig for the {{HighlightParam|<target>}} and the {{HighlightParam|<device tree>}} for your board and then execute the <code>make all</code> command:

  {{PC$}} make {{HighlightParam|<target>}}_defconfig
  {{PC$}} make DEVICE_TREE={{HighlightParam|<device tree>}} {{HighlightParam|all}}

Use help to list other targets than {{HighlightParam|all}}:
  {{PC$}} make help

Optionally
* '''KBUILD_OUTPUT''' can be used to change the output build directory in order to compile several targets in the source directory. For example:

  {{PC$}} export KBUILD_OUTPUT={{HighlightParam|<path>}}

* '''DEVICE_TREE''' can also be exported to your environment when only one board is supported. For example:

  {{PC$}} export DEVICE_TREE={{HighlightParam|<device-tree>}}

The result is the following:

  {{PC$}} export KBUILD_OUTPUT={{HighlightParam|<path>}}
  {{PC$}} export DEVICE_TREE={{HighlightParam|<device tree>}}
  {{PC$}} make {{HighlightParam|<target>}}_defconfig
  {{PC$}} make {{HighlightParam|all}}

Examples from [[STM32MP15 U-Boot]]:

The [[Boot_chain_overview#STM32MP15 boot chain|boot chain]] for {{MicroprocessorDevice | device=15}} use {{Highlight|stm32mp15_trusted_defconfig}}:

  {{PC$}} make {{HighlightParam|stm32mp15_trusted_defconfig}}
  {{PC$}} make DEVICE_TREE={{HighlightParam|stm32mp157f-dk2}} all

  {{PC$}} export KBUILD_OUTPUT={{HighlightParam|../build/stm32mp15_trusted}}
  {{PC$}} export DEVICE_TREE={{HighlightParam|stm32mp157c-ev1}}
  {{PC$}} make {{HighlightParam|stm32mp15_trusted_defconfig}}
  {{PC$}} make all

=== Output files ===
The resulting U-Boot files are located in your build directory (U-Boot or KBUILD_OUTPUT).

Since {{EcosystemRelease | revision=3.0.0}} , two U-Boot files are used by ST boards to generate FIP used by FSBL TF-A, with or without OP-TEE support:
* {{HighlightParam|BL33_CFG}}={{Highlight|'''u-boot.dtb'''}} : the U-Boot device tree, selected by DEVICE_TREE, loaded by TF-A BL2 and amended by secure monitor (SPMIN or OP-TEE)
* {{HighlightParam|BL33}}={{Highlight|'''u-boot-nodtb.bin'''}}: the U-Boot executable, loaded by TF-A BL2 started by secure monitor with BL33_CFG as parameter

Nota: All the compiled device tree are available in $KBUILD_OUTPUT/arch/arm/dts/*.dtb.<br/>You can select them as BL33_CFG without U-Boot recompilation.

See [[TF-A_overview]] for FIP details.

The file used to debug with gdb is
* u-boot : elf file for U-Boot
<div class="mw-collapsible mw-collapsed">

For {{EcosystemRelease | revision=2.1.0 | range=and before}}: {{Highlight|u-boot.stm32}} : U-Boot binary with STM32 image header, including device tree selected by DEVICE_TREE,  loaded by TF-A<div class="mw-collapsible-content">


This behavior can be restored if you activate {{HighlightParam|CONFIG_STM32MP15x_STM32IMAGE}} in your defconfig of {{EcosystemRelease | revision=3.0.0}}

This temporary option is only introduced to facilitate the FIP migration but it will be removed in the next EcosystemRelease.

The STM32 image format (*.stm32) is managed by mkimage U-Boot tools and [[Signing_tool]]. It is requested by ROM code and TF-A without FIP support (see [[STM32 header for binary files]] for details).</div></div>


== References ==<references/>

<noinclude>

[[Category:U-Boot]]
{{PublicationRequestId | 16007|2020-05-05}}</noinclude>
(2 intermediate revisions by 2 users not shown)
Line 253: Line 253:
   
 
This environment can be modified and saved in the boot device. When it is present, it is loaded during U-Boot initialization:
 
This environment can be modified and saved in the boot device. When it is present, it is loaded during U-Boot initialization:
* To boot from ''e''•MMC/SD card (CONFIG_ENV_IS_IN_MMC): at the end of the partition indicated by config field "u-boot,mmc-env-partition" in device-tree (partition named "ssbl" for ST boards).
+
* To boot from ''e''•MMC/SD card (CONFIG_ENV_IS_IN_MMC): at the end of the partition indicated by config field "u-boot,mmc-env-partition" in device-tree (for ST boards: partition named "fip" in {{EcosystemRelease | revision=3.0.0 | range=and after}} with FIP support or partition named "ssbl" without FIP support).
 
* To boot from NAND Flash memory (CONFIG_ENV_IS_IN_UBI): in the two UBI volumes "config" (CONFIG_ENV_UBI_VOLUME) and "config_r"  (CONFIG_ENV_UBI_VOLUME_REDUND).
 
* To boot from NAND Flash memory (CONFIG_ENV_IS_IN_UBI): in the two UBI volumes "config" (CONFIG_ENV_UBI_VOLUME) and "config_r"  (CONFIG_ENV_UBI_VOLUME_REDUND).
 
* To boot from NOR Flash memory (CONFIG_ENV_IS_IN_SPI_FLASH): the u-boot_env mtd parttion (at offset CONFIG_ENV_OFFSET).
 
* To boot from NOR Flash memory (CONFIG_ENV_IS_IN_SPI_FLASH): the u-boot_env mtd parttion (at offset CONFIG_ENV_OFFSET).