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.

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

  • 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.

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 (partition named "ssbl" for ST boards).
  • 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

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:

  • bootargs
  • kernel + device tree + ramdisk files (optional)
  • FIT image

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]

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://gitlab.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).

The U-Boot generated files when TF-A is used as FSBL, with or without OP-TEE:

  • u-boot.stm32 : U-Boot binary with STM32 image header, loaded by TF-A

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

The files used to debug with gdb are

  • u-boot : elf file for U-Boot

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.

* 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://gitlab.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>


=== SPL: alternate FSBL ===
==== 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 SSBL 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 }}).

=== 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:
* 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.

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 boards).
* 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

==== 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: 
* bootargs
* kernel + device tree + ramdisk files (optional)
* FIT image

=== 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 ==
=== 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://gitlab.denx.de/u-boot/u-boot.git or https://github.com/u-boot/u-boot</ref>

  {{PC$}} git clone https://gitlab.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).

The U-Boot generated files when TF-A is used as FSBL, with or without OP-TEE:
* {{Highlight|'''u-boot.stm32'''}} : U-Boot binary with STM32 image header, loaded by TF-A

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

The files used to debug with gdb are
* u-boot : elf file for U-Boot

== References ==<references/>

<noinclude>

[[Category:U-Boot]]
{{PublicationRequestId | 16007|2020-05-05}}</noinclude>
(No difference)