Difference between revisions of "U-Boot overview"

[quality revision] [unchecked revision]
imported>Frq07632
m
(update for v1.1.0)

Template:ArticleMainWriter

Template:ArticleApprovedVersionArticleDraftVersion


1 Das U-Boot[edit]

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

 
PC $> git clone git://gitgit@gitlab.denx.de:u-boot/u-boot.git

Reading the README file is recommended. It covers the following topics:

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

2 U-Boot overview[edit]

Zoom out to STM32MPU Embedded Software

The same U-Boot source can generate 2 pieces of firmware used in the STM32 MPU boot chain: SPL and U-Boot

  • Trusted boot chain: U-Boot as SSBL
  • Basic boot chain: SPL as FSBL and U-Boot as SSBL
Warning.png The basic boot chain is not supported/promoted by STMicroelectronics to make product.

The basic is provided as example to have the simplest SSBL and to support the up-stream effort in U-Boot communauty. But if you use SPL and the secure monitor provided by U-Boot, we have many known limitation on power, secure access to register, and limited features (ST32CubeProgrammer / boot from NAND). We are not plan to be removed them.


2.1 SPL: FSBL for basic boot[edit]

The U-Boot SPL or just SPL is the first stage boot loader (FSBL) for the basic boot chain.
It is a small binary (bootstrap utility), generated from the U-Boot source, which fits in the internal and limited embedded RAM:

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

2.2 U-Boot: SSBL[edit]

U-Boot is the default second stage boot loader (SSBL) for the STM32 MPU platforms for the 2 boot chains, trusted and basic:

  • it is configurable and expendable
  • it has a simple command line interface (CLI), usually over a serial console port for interaction with the user
  • it provides scripting capabilities
  • it loads the kernel into RAM and passes control to the kernel
  • it manages many internal and external devices like NAND, NOR, Ethernet, USB
  • it has many supported features and commands for
    • file systems: FAT, UBI/UBIFS, JFFS
    • IP stack: FTP
    • display: LCD, HDMI, BMP for splashcreen
    • USB: host profile (mass storage) or device profile (DFU stack)

2.3 SPL phases[edit]

The SPL runs through the main following phases in SYSRAM:

  • board_init_f(): init drivers up to DDR initialisation (mininimal stack and heap: CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN)
  • configure heap in DDR (CONFIG_SPL_SYS_MALLOC_F_LEN)
  • board_init_r(): init other drivers activated in the SPL device tree
  • load U-Boot (or Kernel in Falcon mode[1]: README.falcon ) and execute it

2.4 U-Boot phases[edit]

U-Boot runs through the following main phases in DDR:

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

3 U-Boot configuration[edit]

The U-Boot binary configuration is based on

  • DeviceTree = U-Boot and SPL binaries include a device tree blob which is parsed at run time

All the configuration flags (CONFIG_) are described in the source code: the README file or documentation directory
example: CONFIG_SPL => activate the SPL compilation.
Hence to compile U-Boot, you need to select the <target> and the device tree for the board to select a predefined configuration.
See #U-Boot_build for examples.

3.1 Kbuild[edit]

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

  • select pre-defined configuration (defconfig file, in configs directory ) and generate the first .config
 
PC $> make <config>_defconfig
  • change U-Boot compile configuration (modify .config) using one of the 5 make command
 
PC $> make menuconfig --> menu based program
 PC $> make config  --> line-oriented configuration
 PC $> make xconfig --> QT program[2]
 PC $> make gconfig --> GTK program
 PC $> make nconfig --> ncurse menu based program

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

Warning: modification is only done locally in the build directory, it is lost after a "make distclean"

So if you want to use your configuration as defconfig:

  
PC $> make savedefconfig

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

The other makefile targets are :

 
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]

See doc/README.fdt-control

The board device tree, with the same binding as the kernel, is integrated with the SPL and U-Boot binaries:

  • appended at the end of the code by default (CONFIG_OF_SEPARATE)
  • embedded in binary (CONFIG_OF_EMBED): useful for debug, allows easy elf file loading

A default device tree is defined in the defconfig file (with CONFIG_DEFAULT_DEVICE_TREE).

You can also select another supported device tree with the make flag DEVICE_TREE
for stm32mp32 boards the file are: arch/arm/dts/stm32mp*.dts

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

or you can provide a precompiled device tree blob (with EXT_DTB option)

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

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

To do this, U-Boot uses some specific device-tree flags to specify 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 each node used in SPL or in U-Boot before relocation but also for each used handle (clock, reset, pincontrol).

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

see U-Boot Command Line Interface

If CONFIG_AUTOBOOT is activated, to enter in this console, you have CONFIG_BOOTDELAY seconds (2s by default) before bootcmd execution (CONFIG_BOOTCOMMAND) by pressing any key when the line below is displayed.

 Hit any key to stop autoboot:  2

4.1 Commands[edit]

The commands are defined cmd/*.c , they are activated under associated configuration flag CONFIG_CMD_*.

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

List of commands extracted from U-Boot Manual (not-exhaustive):

  • Information Commands
    • bdinfo - print Board Info structure
    • coninfo - print console devices and informations
    • flinfo - print FLASH memory information
    • iminfo - print header information for application image
    • help - print online help
  • Memory Commands
    • base - print or set 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 - print FLASH memory information
    • erase - erase FLASH memory
    • protect - enable or disable FLASH write protection
    • mtdparts - define a Linux compatible MTD partition scheme
  • Execution Control Commands
    • source - run script from memory
    • bootm - boot application image from memory
    • go - start application at address 'addr'
  • Download Commands
    • bootp - boot image via network using BOOTP/TFTP protocol
    • dhcp - invoke DHCP client to obtain IP/boot params
    • loadb - load binary file over serial line (kermit mode)
    • loads - load S-Record file over serial line
    • rarpboot- boot image via network using RARP/TFTP protocol
    • tftpboot- boot image via network using TFTP protocol
  • Environment Variables Commands
    • printenv- print environment variables
    • saveenv - save environment variables to persistent storage
    • setenv - set environment variables
    • run - run commands in an environment variable
    • bootd - boot default, i.e., run 'bootcmd'
  • Flattened Device Tree support
    • fdt addr - select FDT to work on
    • fdt list - print one level
    • fdt print - recursive print
    • fdt mknode - create new nodes
    • fdt set - set node properties
    • fdt rm - remove nodes or properties
    • fdt move - move FDT blob to new address
    • fdt chosen - fixup dynamic info
  • Special Commands
    • i2c - I2C sub-system
  • Storage devices
  • Miscellaneous Commands
    • echo - echo args to console
    • reset - Perform RESET of the CPU
    • sleep - delay execution for some time
    • version - print monitor version

To add a new command, see doc/README.commands

4.2 U-Boot environment variables[edit]

The U-Boot behavior is configured with environment variables.

see Manual and README / Environment Variables

By default the env is NOT saved (CONFIG_ENV_IS_NOWHERE), only the default environment is used (saveenv command is not working)

You can modify this default environment On first boot U-Boot use a default environment embedded in the 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).

You can also choose one location with configuration flags:

The environment can modify and saved in the boot device; it is loaded when it is present:

  • for eMMC/SDCARD boot, in the bootable ext4 partition "bootfs" (CONFIG_ENV_IS_IN_MMC):
    in file CONFIG_ENV_IS_IN_FLASHEXT4_FILE="uboot.env"
  • for NAND boot(CONFIG_ENV_IS_IN_SPIUBI), in the two UBI volumes "config" (CONFIG_ENV_IS_IN_FATUBI_VOLUME) and "config_r" (CONFIG_ENV_ISUBI_INVOLUME_NANDREDUND).
  • for NOR boot (CONFIG_ENV_IS_IN_UBISPI_FLASH), in the uboot_env mtd parttion CONFIG_ENV_IS_IN_EEPROMOFFSET=0x00280000

4.2.1 env command[edit]

The "env" command allow to display, modify and save the enviroment in U-Boot console.

Template: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: restore default environment and save it:

Template:BOARD$ env default -a Template:BOARD$ env save

4.2.2 bootcmd[edit]

Autoboot command: defines the command executed when U-Boot starts (CONFIG_BOOTCOMMAND).

But you can change this variable in CONFIG_EXTRA_ENV_SETTINGS (after BOOTENV macro needed for #Generic Distro configuration).

#define CONFIG_EXTRA_ENV_SETTINGS \
	"stdin=serial\0" \
	"stdout=serial\0" \
	"stderr=serial\0" \
	"kernel_addr_r=0xc2000000\0" \
	"fdt_addr_r=0xc4000000\0" \
	"scriptaddr=0xc4100000\0" \
	"pxefile_addr_r=0xc4200000\0" \
	"splashimage=0xc4300000\0"  \
	"ramdisk_addr_r=0xc4400000\0" \
	"fdt_high=0xffffffff\0" \
	"initrd_high=0xffffffff\0" \
	BOOTENV \
	"bootcmd=run bootcmd_mmc0\0"

4.3 Generic Distro configuration[edit]

see doc/README.distro

This feature is activated for ST boards (CONFIG_DISTRO_DEFAULTS):

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

With DISTRO the default command executed: include/config_distro_bootcmd.h

 bootcmd=run distro_bootcmd

This script will try any device found in the variable 'boot_targets' and execute the associated bootcmd.

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

 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 searchs for a configuration file extlinux.conf in a bootable device, this file defines the kernel configuration to use:

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

4.4 U-Boot scripting capabilities[edit]

"Script files" are command sequences that will be executed by U-Boot's command interpreter; this feature is especially useful when you configure U-Boot to use a real shell (hush) as command interpreter.

See U-Boot script manual for example.

5 U-Boot build[edit]

5.1 Prerequisites[edit]

You need:

 
PC $> git clone https://github.com/STMicroelectronics/u-boot

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

5.1.1 ARM cross compiler[edit]

You need to have a cross compiler [5] installed on your Host (X86_64, i686, ...) for the targeted Device architecture = ARM, the environment variables ($PATH and $CROSS_COMPILE) need to be configured in your shell.

You can use gcc for ARM, available in:

  1. the SDK toolchain
    See Cross-compile with OpenSTLinux SDK, PATH and CROSS_COMPILE are automatically updated.
  2. an existing package (for example, on Ubuntu/Debian: (PC $> sudo apt-get install gcc-arm-linux-gnueabihf)
  3. an existing toolchain:

for example: 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 it in $HOME,
and you need to update your environment:

 
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.2 Compilation[edit]

In the U-Boot source directory, you need to select the <target> and the <device tree> for your configuration and then execute the "make all" command.

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

KBUILD_OUTPUT can be used optionally to change the output directory if you want to compile several targets or don't compile in the source directory, for example:

 
PC $> export KBUILD_OUTPUT=../build/basic

DEVICE_TREE can be also exported to your environment when you support only one board, for example:

 
PC $> export DEVICE_TREE=stm32mp157c-ev1

For all the stm32mp15 family, we manage 3 configurations:

  • stm32mp15_trusted_defconfig: trusted boot chain, U-Boot (without SPL) is unsecure and uses Secure monitor from TF-A
  • stm32mp15_optee_defconfig: trusted boot chain, U-Boot (without SPL) is unsecure and uses Secure monitor from SecureOS = OP-TEE
  • stm32mp15_basic_defconfig: basic boot chain, with an SPL as FSBL, U-BOOT is secure and installs monitor with PSCI

The board diversity is only managed with the device tree.

Examples from STM32MP15 U-Boot:

 
PC $> export KBUILD_OUTPUT=../build/basic
 PC $> make stm32mp15_basic_defconfig
 PC $> make DEVICE_TREE=stm32mp157c-<board> all
 
PC $> export KBUILD_OUTPUT=../build/trusted
 PC $> make stm32mp15_trusted_defconfig
 PC $> make DEVICE_TREE=stm32mp157c-<board> all
 
PC $> export KBUILD_OUTPUT=../build/trusted
 PC $> export DEVICE_TREE=stm32mp157c-ev1
 PC $> make stm32mp15_trusted_defconfig
 PC $> make all

Use help to list other targets:

 
PC $> make help

5.3 Output files[edit]

The resulting U-Boot files are present in your build directory (U-Boot or KBUILD_OUTPUT) and SPL Images are in the spl subdirectory.

STM32 image format (*.stm32) is managed by mkimage U-Boot tools and is requested by boot ROM (for basic boot chain) or by TF-A (for trusted boot chain).

  • u-boot.stm32 : U-Boot binary with STM32 image header => SSBL for Trusted boot chain
  • u-boot.img : U-Boot binary with uImage header => SSBL for Basic boot chain
  • u-boot : elf file, used to debug with gdb
  • spl/u-boot-spl.stm32 : SPL binary with STM32 image header => FSBL for Basic boot chain
  • spl/u-boot-spl : elf file, used to debug with gdb

6 References[edit]

<noinclude>

{{ArticleMainWriter|PatrickD}}

{{   ArticleApprovedVersion|PatrickD|GeraldB(Passed 13Nov'18), PatriceC(Done 13Nov'18), LionelD(Done 12Nov'18),NicolasLB(Done 13Nov'18), YannG(Passed 15Nov'18ArticleDraftVersion| PatrickD | GeraldB(NotDone), PatriceC(NotDone), LionelD(NotDone),NicolasLB(NotDone), YannG(NotDone), NathalieS/Jean-ChristopheT(NotDone) |27 Nov'18 31 Jan'19 | Philip S. - 19 Feb '18 | 31 Jan25Jun'19 }} 

[[Category:U-Boot]]</noinclude>


== Das U-Boot ==
[https://en.wikipedia.org/wiki/Das_U-Boot Das U-Boot] ("the Universal Boot Loader" or just U-Boot) is an open-source boot loader, which 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]
* The official [https://www.denx.de/wiki/U-Boot/SourceCode '''source code'''] is available with [https://git-scm.com/ git] repository at [http://githttps://gitlab.denx.de/?p=u-boot.git;a=summary git.denx.de]
  {{PC$}} git clone git://git.denx.de/u-boot]
  {{PC$}} git clone git@gitlab.denx.de:u-boot/u-boot.git

Reading the {{CodeSource | U-Boot | README | README file}} is recommended. It covers the following topics:
* the source file tree structure
* the meaning of the CONFIG defines
* instructions for building U-Boot
* a brief description of the Hush shell
* a list of common environment variables

== U-Boot overview ==
[[File: STM32MPU Embedded Software architecture overview.png|link=STM32MPU Embedded Software architecture overview|thumb|Zoom out to STM32MPU Embedded Software]]
The same U-Boot source can generate 2 pieces of firmware used in the [[Boot_chains_overview#STM32MP boot chains|STM32 MPU boot chain]]: SPL and U-Boot
* Trusted boot chain: U-Boot as SSBL
* Basic boot chain: SPL as FSBL and U-Boot as SSBL

{{Warning | The basic boot chain is not supported/promoted by STMicroelectronics to make product.}} 

The basic is provided as example to have the simplest SSBL and to support the up-stream effort in U-Boot communauty. But if you use SPL and the secure monitor provided by U-Boot, we have many known limitation on power, secure access to register, and limited features (ST32CubeProgrammer / boot from NAND). We are not plan to be removed them.
<br clear=all>


=== SPL: FSBL for basic boot===
The '''U-Boot SPL''' or just '''SPL''' is the first stage boot loader (FSBL) for [[Boot_chains_overview#STM32MP boot chains|the basic boot chain]].<br/>It is a small binary (bootstrap utility), generated from the U-Boot source, which fits in the internal and limited embedded RAM:
* It is loaded by the ROM code
* it does the initial CPU and board configuration: clocks and DDR
* it loads the SSBL (U-Boot) into DDR memory

=== U-Boot: SSBL ===
'''U-Boot''' is the default second stage boot loader (SSBL) for the STM32 MPU platforms for the 2 boot chains, [[Boot_chains_overview#STM32MP boot chains|trusted and basic]]:
* it is configurable and expendable
* it has a simple command line interface (CLI), usually over a serial console port for interaction with the user
* it provides scripting capabilities
* it loads the kernel into RAM and passes control to the kernel
* it manages many internal and external devices like NAND, NOR, Ethernet, USB
* it has many supported features and commands for
** file systems: FAT, UBI/UBIFS, JFFS
** IP stack: FTP
** display: LCD, HDMI, BMP for splashcreen
** USB: host profile (mass storage) or device profile (DFU stack)

=== SPL phases ===
The '''SPL''' runs through the main following phases in SYSRAM:
* '''board_init_f()''': init drivers up to DDR initialisation (mininimal stack and heap: CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN)
* configure heap in DDR (CONFIG_SPL_SYS_MALLOC_F_LEN)
* '''board_init_r()''': init other drivers activated in the SPL device tree
* load 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 }}) and execute it

=== U-Boot phases ===
'''U-Boot''' runs through the following main  phases in DDR:
* '''Pre-relocation''' initialization (common/board_f.c): minimal init (cpu, clock, reset, ddr, console,...) running at the load address CONFIG_SYS_TEXT_BASE
* '''Relocation''': copy the code to the end of DDR
* '''Post-relocation initialization''':(common/board_r.c): init all the drivers
* '''Execution of commands''': through autoboot (CONFIG_AUTOBOOT) or console shell
** execute the boot command ([[#bootcmd|bootcmd=CONFIG_BOOTCOMMAND]] by default): <br/>for example, execute the command 'bootm' to: 
*** load and check images (kernel, device tree, ramdisk....)
*** fixup kernel device tree
*** install secure monitor (optional)
*** pass control to the Linux kernel (or other 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 "make menuconfig" 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''' defines in {{CodeSource | U-Boot | include/configs/ | include/configs/stm32mp*.h}}<br/>the file name is configured by CONFIG_SYS_CONFIG_NAME<br/>(these flags are progressively migrating to Kconfig)<br/>for stm32mp157: we use {{CodeSource | U-Boot | include/configs/stm32mp1.h | include/configs/stm32mp1.h}} file

* '''[[Device_tree|DeviceTree]]''' = U-Boot and SPL binaries include a device tree blob which is parsed at run time
All the configuration flags (CONFIG_) are described in the source code: the {{CodeSource | U-Boot | README | README}} file or {{CodeSource | U-Boot | doc/ | documentation directory}}<br/>example: CONFIG_SPL => activate the SPL compilation.<br />

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

See [[#U-Boot_build]] for examples.

=== Kbuild ===

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

* select pre-defined configuration (defconfig file, in {{CodeSource | U-Boot | configs/ | configs directory }}) and generate the first '''.config'''
  {{PC$}} make <config>_defconfig

* change U-Boot compile configuration (modify .config) using one of the 5 make command
  {{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: modification is only done locally in the build directory, it is lost after a "make distclean"

So if you want to use your configuration as defconfig:
   {{PC$}} make savedefconfig

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

The other makefile targets are :

  {{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 ===
See {{CodeSource | U-Boot | doc/README.fdt-control | doc/README.fdt-control}}

The board device tree, with the same binding as the kernel, is integrated with the SPL and U-Boot binaries:
* appended at the end of the code by default (CONFIG_OF_SEPARATE)
* embedded in binary (CONFIG_OF_EMBED): useful for debug, allows easy elf file loading

A default device tree is defined in the defconfig file (with CONFIG_DEFAULT_DEVICE_TREE).

You can also select another supported device tree with the make flag DEVICE_TREE<br/> for stm32mp32 boards the file are: {{CodeSource | U-Boot | arch/arm/dts/ | arch/arm/dts/stm32mp*.dts}}
   {{PC$}} make DEVICE_TREE=<dts-file-name>


or you can provide a precompiled device tree blob (with EXT_DTB option)
   {{PC$}} make EXT_DTB=boot/<dts-file-name>.dtb

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

To do this, U-Boot uses some specific device-tree flags to specify 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 each node''' used in SPL or in U-Boot before relocation but also for each used handle (clock, reset, pincontrol).

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

If CONFIG_AUTOBOOT is activated, to enter in this console, you have CONFIG_BOOTDELAY seconds (2s by default) before [[#bootcmd|bootcmd]] execution (CONFIG_BOOTCOMMAND) by pressing any key when the line below is displayed.
  Hit any key to stop autoboot:  2

=== Commands ===
The commands are defined {{CodeSource | U-Boot | cmd/ | cmd/*.c}}, they are activated under associated configuration flag '''CONFIG_CMD_*'''.

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

List of 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 - print Board Info structure
** coninfo - print console devices and informations
** flinfo - print FLASH memory information
** iminfo - print header information for application image
** help - print online help
* [http://www.denx.de/wiki/view/DULG/UBootCmdGroupMemory Memory Commands]
** base - print or set 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 - print FLASH memory information
** erase - erase FLASH memory
** protect - enable or disable FLASH write protection
** mtdparts - define a Linux compatible MTD partition scheme
* [http://www.denx.de/wiki/view/DULG/UBootCmdGroupExec Execution Control Commands]
** source - run script from memory
** bootm - boot application image from memory
** go - start application at address 'addr'
* [http://www.denx.de/wiki/view/DULG/UBootCmdGroupDownload Download Commands]
** bootp - boot image via network using BOOTP/TFTP protocol
** dhcp - invoke DHCP client to obtain IP/boot params
** loadb - load binary file over serial line (kermit mode)
** loads - load S-Record file over serial line
** rarpboot- boot image via network using RARP/TFTP protocol
** tftpboot- boot image via network using TFTP protocol
* [http://www.denx.de/wiki/view/DULG/UBootCmdGroupEnvironment Environment Variables Commands]
** printenv- print environment variables
** saveenv - save environment variables to persistent storage
** setenv - set environment variables
** run - run commands in an environment variable
** bootd - boot default, i.e., run 'bootcmd'
* [http://www.denx.de/wiki/view/DULG/UBootCmdFDT Flattened Device Tree support]
** fdt addr - select FDT to work on
** fdt list - print one level
** fdt print - recursive print
** fdt mknode - create new nodes
** fdt set - set node properties
** fdt rm - remove nodes or properties
** fdt move - move FDT blob to new address
** fdt chosen - fixup dynamic info
* [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 - echo args to console
** reset - Perform RESET of the CPU
** sleep - delay execution for some time
** version - print monitor version

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

=== U-Boot environment variables ===

The U-Boot behavior is configured with environment variables.

see [http://www.denx.de/wiki/view/DULG/UBootEnvVariables Manual] and {{CodeSource | U-Boot | README | README}} / Environment Variables
By default the env is NOT saved (CONFIG_ENV_IS_NOWHERE), only the default environment is used (saveenv command is not working)

You can modify this default environment On first boot U-Boot use a default environment embedded in the 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).
You The environment can also choose one location with configuration flags:
* modify and saved in the boot device; it is loaded when it is present:
* for eMMC/SDCARD boot, in the bootable ext4 partition "bootfs" (CONFIG_ENV_IS_IN_MMC

* CONFIG_ENV_IS_IN_FLASH
* ): <br/>in file CONFIG_ENV_EXT4_FILE="uboot.env"
* for NAND boot(CONFIG_ENV_IS_IN_SPI
* CONFIG_ENV_IS_IN_FAT
* CONFIG_ ENV_IS_IN_NAND
* UBI), in the two UBI volumes "config" (CONFIG_ENV_UBI_VOLUME) and "config_r"  (CONFIG_ENV_UBI_VOLUME_REDUND).
* for NOR boot (CONFIG_ENV_IS_IN_UBI
* CONFIG_ENV_IS_IN_EEPROM

==== SPI_FLASH), in the uboot_env mtd parttion CONFIG_ENV_OFFSET=0x00280000

==== env command ====

The "env" command allow to display, modify and save the enviroment 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: restore default environment and save it:

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

==== bootcmd ====
Autoboot command: defines the command executed when U-Boot starts (CONFIG_BOOTCOMMAND).

But you can change this variable in CONFIG_EXTRA_ENV_SETTINGS (after BOOTENV macro needed for [[#Generic Distro configuration]]).
<pre>

#define CONFIG_EXTRA_ENV_SETTINGS \
	"stdin=serial\0" \
	"stdout=serial\0" \
	"stderr=serial\0" \
	"kernel_addr_r=0xc2000000\0" \
	"fdt_addr_r=0xc4000000\0" \
	"scriptaddr=0xc4100000\0" \
	"pxefile_addr_r=0xc4200000\0" \
	"splashimage=0xc4300000\0"  \
	"ramdisk_addr_r=0xc4400000\0" \
	"fdt_high=0xffffffff\0" \
	"initrd_high=0xffffffff\0" \
	BOOTENV \
	"bootcmd=run bootcmd_mmc0\0"</pre>


=== Generic Distro configuration ===

see {{CodeSource | U-Boot | doc/README.distro | doc/README.distro}}

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

With DISTRO the default command executed: {{CodeSource | U-Boot | include/config_distro_bootcmd.h}}
  bootcmd=run distro_bootcmd

This script will try any device found in the variable 'boot_targets' and execute the associated bootcmd.

Example for device mmc0, mmc1, mmc2, pxe and ubifs:
  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 searchs for a configuration file '''extlinux.conf''' in a bootable device, this file defines the kernel configuration to use: 
* bootargs
* kernel + device tree + ramdisk files (optional)
* FIT image

=== U-Boot scripting capabilities ===

"Script files" are command sequences that will be executed by U-Boot's command interpreter; this feature is especially useful when you 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 example.

== U-Boot build ==
=== Prerequisites ===

You need:
* a PC with Linux and tools: 
** see [[PC_prerequisites]]
** [[#ARM cross compiler]]
* U-Boot source code
** the latest STMicroelectonics U-Boot version
*** tar.xz file from Developer Package (for example [[STM32MP1_Developer_Package#Installing_the_U-Boot|STM32MP1]])
*** from GITHUB<ref>https://github.com/STMicroelectronics/u-boot</ref>, with git command
  {{PC$}} git clone https://github.com/STMicroelectronics/u-boot
:* from the Mainline U-Boot in official GIT repository <ref>http://git.denx.de/u-boot.git or https://github.com/u-boot/u-boot</ref>

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

==== ARM cross compiler ====

You need to have a cross compiler <ref>https://en.wikipedia.org/wiki/Cross_compiler</ref> installed on your Host (X86_64, i686, ...) for the targeted Device architecture = ARM, the environment variables ($PATH and $CROSS_COMPILE) need to be configured in your shell.

You can use gcc for ARM, available in:
# the SDK toolchain<br/>See [[Cross-compile with OpenSTLinux SDK]], PATH and CROSS_COMPILE are automatically updated.
# an existing package (for example, on Ubuntu/Debian: ({{PC$}} sudo apt-get install gcc-arm-linux-gnueabihf)
# an existing toolchain:
#* gcc v8 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:
'''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/
unzip it in $HOME,<br/>and you need to update your environment:
  {{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, you need to select the <target> and the <device tree> for your configuration and then execute the "make all" command.

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

'''KBUILD_OUTPUT''' can be used optionally to change the output directory if you want to compile several targets or don't compile in the source directory, for example:
  {{PC$}} export KBUILD_OUTPUT=../build/basic

'''DEVICE_TREE''' can be also exported to your environment when you support only one board, for example:
  {{PC$}} export DEVICE_TREE=stm32mp157c-ev1

For all the stm32mp15 family, we manage 3 configurations:
* stm32mp15_trusted_defconfig: [[Boot_chains_overview#STM32MP boot chains|trusted boot chain]], U-Boot (without SPL) is unsecure and uses Secure monitor from TF-A
* stm32mp15_optee_defconfig: [[Boot_chains_overview#STM32MP boot chains|trusted boot chain]], U-Boot (without SPL) is unsecure and uses Secure monitor from SecureOS = [[OP-TEE overview|OP-TEE]]
* stm32mp15_basic_defconfig: [[Boot_chains_overview#STM32MP boot chains|basic boot chain]], with an SPL as FSBL, U-BOOT is secure and installs monitor with PSCI

The board diversity is only managed with the device tree.

Examples from [[STM32MP15 U-Boot]]:
  {{PC$}} export KBUILD_OUTPUT=../build/basic
  {{PC$}} make stm32mp15_basic_defconfig
  {{PC$}} make DEVICE_TREE=stm32mp157c-<board> all

  {{PC$}} export KBUILD_OUTPUT=../build/trusted
  {{PC$}} make stm32mp15_trusted_defconfig
  {{PC$}} make DEVICE_TREE=stm32mp157c-<board> all

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

Use help to list other targets:
  {{PC$}} make help

=== Output files ===
The resulting U-Boot files are present in your build directory (U-Boot or KBUILD_OUTPUT) and SPL Images are in the spl subdirectory.

STM32 image format (*.stm32) is managed by mkimage U-Boot tools and is requested by boot ROM (for basic boot chain) or by TF-A (for trusted boot chain).

* '''u-boot.stm32''' : U-Boot binary with STM32 image header => SSBL for Trusted boot chain
* '''u-boot.img''' : U-Boot binary with uImage header => SSBL for Basic boot chain

* u-boot : elf file, used to debug with gdb
* '''spl/u-boot-spl.stm32''' : SPL binary with STM32 image header => FSBL for Basic boot chain
* spl/u-boot-spl : elf file, used to debug with gdb

== References ==<references/>
Line 2: Line 2:
 
{{ArticleMainWriter|PatrickD}}
 
{{ArticleMainWriter|PatrickD}}
   
{{   ArticleApprovedVersion|PatrickD|GeraldB(Passed 13Nov'18), PatriceC(Done 13Nov'18), LionelD(Done 12Nov'18),NicolasLB(Done 13Nov'18), YannG(Passed 15Nov'18), NathalieS/Jean-ChristopheT(NotDone) |27 Nov'18 | Philip S. - 19 Feb '18 | 31 Jan'19 }}  
+
{{ ArticleDraftVersion| PatrickD | GeraldB(NotDone), PatriceC(NotDone), LionelD(NotDone),NicolasLB(NotDone), YannG(NotDone), NathalieS/Jean-ChristopheT(NotDone) | 31 Jan'19 | Philip S. - 19 Feb '18 | 25Jun'19 }}  
   
 
[[Category:U-Boot]]
 
[[Category:U-Boot]]
Line 11: Line 11:
 
* Official website: [https://www.denx.de/wiki/U-Boot https://www.denx.de/wiki/U-Boot]
 
* 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 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]
* The official [https://www.denx.de/wiki/U-Boot/SourceCode '''source code'''] is available with [https://git-scm.com/ git] repository at [http://git.denx.de/?p=u-boot.git;a=summary git.denx.de]
+
* The official [https://www.denx.de/wiki/U-Boot/SourceCode '''source code'''] is available with [https://git-scm.com/ git] repository at [https://gitlab.denx.de/u-boot/u-boot]
   {{PC$}} git clone git://git.denx.de/u-boot.git
+
   {{PC$}} git clone git@gitlab.denx.de:u-boot/u-boot.git
   
 
Reading the {{CodeSource | U-Boot | README | README file}} is recommended. It covers the following topics:
 
Reading the {{CodeSource | U-Boot | README | README file}} is recommended. It covers the following topics:
Line 26: Line 26:
 
* Trusted boot chain: U-Boot as SSBL
 
* Trusted boot chain: U-Boot as SSBL
 
* Basic boot chain: SPL as FSBL and U-Boot as SSBL
 
* Basic boot chain: SPL as FSBL and U-Boot as SSBL
  +
  +
{{Warning | The basic boot chain is not supported/promoted by STMicroelectronics to make product.}}
  +
  +
The basic is provided as example to have the simplest SSBL and to support the up-stream effort in U-Boot communauty. But if you use SPL and the secure monitor provided by U-Boot, we have many known limitation on power, secure access to register, and limited features (ST32CubeProgrammer / boot from NAND). We are not plan to be removed them.
  +
 
<br clear=all>
 
<br clear=all>
   
Line 145: Line 150:
 
To do this, U-Boot uses some specific device-tree flags to specify if the associated driver is initialized prior to U-Boot relocation and/or if the associated node is present in SPL :
 
To do this, U-Boot uses some specific device-tree flags to specify 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-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
 
* '''u-boot,dm-spl''' => present in SPL
   
Line 227: Line 233:
 
see [http://www.denx.de/wiki/view/DULG/UBootEnvVariables Manual] and {{CodeSource | U-Boot | README | README}} / Environment Variables
 
see [http://www.denx.de/wiki/view/DULG/UBootEnvVariables Manual] and {{CodeSource | U-Boot | README | README}} / Environment Variables
   
By default the env is NOT saved (CONFIG_ENV_IS_NOWHERE), only the default environment is used (saveenv command is not working)
+
On first boot U-Boot use a default environment embedded in the 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).
  +
 
  +
The environment can modify and saved in the boot device; it is loaded when it is present:
  +
* for eMMC/SDCARD boot, in the bootable ext4 partition "bootfs" (CONFIG_ENV_IS_IN_MMC): <br/>in file CONFIG_ENV_EXT4_FILE="uboot.env"
  +
* for NAND boot(CONFIG_ENV_IS_IN_UBI), in the two UBI volumes "config" (CONFIG_ENV_UBI_VOLUME) and "config_r"  (CONFIG_ENV_UBI_VOLUME_REDUND).
  +
* for NOR boot (CONFIG_ENV_IS_IN_SPI_FLASH), in the uboot_env mtd parttion CONFIG_ENV_OFFSET=0x00280000
  +
 
  +
==== env command ====
  +
 
  +
The "env" command allow to display, modify and save the enviroment 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 ...]
   
You can modify this default environment 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).
+
Example: restore default environment and save it:
   
You can also choose one location with configuration flags:
+
{{BOARD$}} env default -a
* CONFIG_ENV_IS_IN_MMC
+
{{BOARD$}} env save
* CONFIG_ENV_IS_IN_FLASH
 
* CONFIG_ENV_IS_IN_SPI
 
* CONFIG_ENV_IS_IN_FAT
 
* CONFIG_ ENV_IS_IN_NAND
 
* CONFIG_ENV_IS_IN_UBI
 
* CONFIG_ENV_IS_IN_EEPROM
 
   
 
==== bootcmd ====
 
==== bootcmd ====