How to configure U-Boot for your board

Applicable for STM32MP13x lines, STM32MP15x lines

This page explains how to configure the U-Boot source for your board.

Many existing ressources [1][2] explain the porting of U-Boot on a new board. This article only provides basic guidelines for STM32MP1 series.

To summarize, you need to configure U-Boot for your <VENDOR> <BOARD> with the following steps:

  1. Add your board device tree: arch/arm/dts/<board>.dts and <board>-u-boot.dtsi.
  2. Create your own board support directory: board/<vendor>/<board>.
  3. Add TARGET_<VENDOR> _<BOARD> in Kconfig.
  4. Create your board defconfig: defconfig/<board>_defconfig.
  5. Add your configuration file : include/configs/<board>.h.

1 Device tree[edit]

Add the board device tree files <board>.dts and <board>-u-boot.dtsi in arch/arm/dts , following the steps below:

  • Copy the Linux kernel device tree in the directory arch/arm/dts : <board>.dts.

E.g for STM32MP13x lines More info.png

 dtb-$(CONFIG_STM32MP13X) += \
 	<STM32MP13 board>.dtb

E.g for STM32MP15x lines More info.png

 dtb-$(CONFIG_STM32MP15X) += \
 	<STM32MP15 board>.dtb 

At this point you can use the generic STM32 MPU defconfig with the STMicroelectronics board directory, but with your board device tree.

The board-specific features are not correctly managed, but should be sufficient for a simple board derived from STMicroelectronics designs.

You can use the STMicroelectronics code with your device tree as follows:

E.g for STM32MP13x lines More info.png

  make stm32mp13_defconfig
  make DEVICE_TREE=<STM32MP13 board> all

E.g for STM32MP15x lines More info.png

  make stm32mp15_defconfig
  make DEVICE_TREE=<STM32MP15 board> all

The next steps are required if the STMicroelectronics generic board does not comply with all of the expected behavioral aspects for your board (for example MAC address not located in OTP, specific PMIC, specific boot command).

1.1 Console[edit]

The U-Boot console use stdout-path defined in the chosen node of the Linux kernel device tree as described in the Linux kernel binding[3].

As the console is used before relocation, you must add the flags u-boot,dm-pre-reloc for each associated nodes (and sub-nodes).

For example in device tree from kernel = <board>.dts:

 / {
 	...
 	chosen {
 		stdout-path = " serial0:115200n8";
 	  };
 	aliases {
 		serial0 = &uart4;
 	};
 	...
 };
 ...
 &uart4 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart4_pins_a>;
 	status = "okay";
 };

And in the U-Boot add-on file = <board>-u-boot.dtsi:

 &uart4 {
 	u-boot,dm-pre-reloc;
 };
 
 &uart4_pins_a {
 	u-boot,dm-pre-reloc;
 	pins1 {
 		u-boot,dm-pre-reloc;
 	};
 	pins2 {
 		u-boot,dm-pre-reloc;
 	};
 };

The variable baudrate, initialized with CONFIG_BAUDRATE value, is used to configure the desired baud rate; the default value is 115200 bauds.

An early DEBUG trace, before the device tree parsing, can be also activated with CONFIG_DEBUG_UART and board_debug_uart_init() (see U-Boot-How to debug page for details).

1.2 Config node[edit]

Some properties in the 'config' node are also used to dynamically configure the U-Boot behavior in the board device tree as follows:

  • Generic U-Boot configuration: doc/device-tree-bindings/config.txt
    • u-boot,mmc-env-partition = name of partition used to save U-Boot environment
    • u-boot,boot-led = name of boot-progress indicator LED
    • u-boot,error-led = name of error indicator LED
  • Some STMicroelectronics properties:
    • st,adc_usb_pd = ADC channels used to check USB power supply
    • st,stm32prog-gpios = GPIO used to force STM32CubeProgrammer mode
    • st,fastboot-gpios = GPIO used to force Android Fastboot mode

These parameters are managed in U-Boot generic code or in STMicroelectronics board code (in line with LEDs and buttons on STM32 MPU boards); they can only be used if your board reuses the associated code.

E.g for STM32MP15x lines More info.png, in arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi , the properties are:

   	config {
   		u-boot,boot-led = "heartbeat";
   		u-boot,error-led = "error";
   		u-boot,mmc-env-partition = "u-boot-env";
   		st,adc_usb_pd = <&adc1 18>, <&adc1 19>;
   		st,fastboot-gpios = <&gpioa 13 GPIO_ACTIVE_LOW>;
   		st,stm32prog-gpios = <&gpioa 14 GPIO_ACTIVE_LOW>;
   	};

1.3 USB OTG node[edit]

The U-Boot drivers for USB OTG internal peripheral, with the compatible st,stm32mp15-hsotg, does not have a full OTG support with USB host and USB device detection; to avoid issue only the gadget driver is used in STM32 MPU boards with drivers/usb/gadget/dwc2_udc_otg.c activated by CONFIG_USB_GADGET_DWC2_OTG; the host driver drivers/usb/host/dwc2.c is not activated with CONFIG_USB_DWC2.

Warning white.png Warning
If you want to activate the HOST driver with CONFIG_USB_DWC2 configuration, the VBUS protection needs to be implemented in you board code to protect the USB power line, avoiding to power up the VBUS when USB HOST is connected on USB OTG port.

Moreover, as only one driver for the same node for OTG internal peripheral must be activated or only the first one will bind in U-Boot , the USB device driver, with CONFIG_USB_GADGET_DWC2_OTG, must be deactivated when you activate the USB HOST driver with CONFIG_USB_DWC2.

Two U-Boot specific properties are added to support the possible USB connection of ID pin and VBUS on the board:

  • u-boot,force-b-session-valid: this property forces USB B session (by deactivating the detection with ID pin) and deactivates VBus sensing. It is used when all these features are managed by the board.
  • u-boot,force-vbus-detection: this property forces Vbus sensing when u-boot,force-b-session-valid is used (typically when the ID pin is not correctly managed).

Examples of USB configuration in <board>-u-boot.dtsi:

  • B session forced as device mode, USB ID pin not used and VBus sensing deactivated:
 &usbotg_hs {
 	u-boot,force-b-session-valid;
 	dr_mode = "peripheral";
 };
  • B session and VBus sensing forced (deactived by default with "force-b-session-valid")
 &usbotg_hs {
 	u-boot,force-b-session-valid;
 	u-boot,force-vbus-detection;
 	dr_mode = "peripheral";
 };

2 Board subdirectory[edit]

Create your own board support subdirectory = board/<vendor>/<board> and add a Makefile file.

You can add any source files needed for your board.

In this Makefile, you can compile the STMicroelectronics files (in board/st/stm32mp1 or in board/st/common) or just copy them as starting point then modify them.

For example board/dhelectronics/dh_stm32mp1/Makefile uses STMicroelectronics board files in ../../st/stm32mp1 directory and local file "board.c"

 ifdef CONFIG_SPL_BUILD
 obj-y += ../../st/stm32mp1/spl.o
 endif

 obj-y += ../../st/stm32mp1/board.o board.o

3 Kconfig[edit]

You need to support your board in Kconfig with a new configuration flag: TARGET_<VENDOR>_<BOARD>

3.1 Arch Kconfig: arch/arm/mach-stm32mp/Kconfig [edit]

  1. Add new CONFIG_TARGET_<VENDOR>_<BOARD>.
  2. Select the required option; at least, select the options:
    • for STM32MP13x lines More info.png: CONFIG_STM32MP13x.
    • for STM32MP15x lines More info.png: CONFIG_STM32MP15x.
  3. Include your board Kconfig (source "board/<vendor>/<board>/Kconfig") in:

E.g for STM32MP15x lines More info.png, the file arch/arm/mach-stm32mp/Kconfig.15x is modified:

 if STM32MP15x
 
 [...]
 choice
 	prompt "STM32MP15x board select"
 	optional
   
   [...]
   
   config TARGET_<VENDOR>_<BOARD>
   	bool "<vendor> <board> board"
   	select STM32MP15x
   	help
 		target the <vendor> <board> board with SOC STM32MP15x
 		managed by board/<vendor>/<board>
 
 endchoice
 
 [...]
 source "board/st/stm32mp1/Kconfig"
 source "board/dhelectronics/dh_stm32mp1/Kconfig"
 source "board/<vendor>/<board>/Kconfig"
  
 endif

3.2 Board Kconfig: board/<vendor>/<board>/Kconfig[edit]

The mininimal content of this file is:

 if TARGET_<VENDOR>_<BOARD>
 
 config SYS_BOARD
 	default "<board>"
 
 config SYS_VENDOR
 	default "<vendor>"
 
 config SYS_CONFIG_NAME
 	default "<config>"
 endif

For example see board/dhelectronics/dh_stm32mp1/Kconfig .

SYS_CONFIG_NAME selects the used configuration file: include/configs/SYS_CONFIG_NAME.h.

4 Defconfig[edit]

Add a new defconfig for your board in configs .

  • copy the correct defconfig to your "<vendor>_<board>_defconfig" (configs/stm32mp13_defconfig or configs/stm32mp15_defconfig )
  • select your new defconfig: make <vendor>_<board>_defconfig
  • use make menuconfig to change your defconfig
    • remove the STMicroelectronics board config (CONFIG_TARGET_ST_STM32MP13x or CONFIG_TARGET_ST_STM32MP15x)
    • add CONFIG_TARGET_<VENDOR>_<BOARD>
    • change CONFIG_DEFAULT_DEVICE_TREE to the name of the board device tree: "<board>"
  • save the updated defconfig: make savedefconfig
  • verify and copy the file "defconfig" in configs/<vendor>_<board>_defconfig

For example see the file configs/stm32mp15_dhcom_basic_defconfig .

5 Configuration file[edit]

The configuration file is the include file in include/configs directory selected in Makefile.autoconf by CONFIG_SYS_CONFIG_NAME.

This file defines the CONFIG_ flags of the boards that are not defined with Kconfig.

For example, in this configuration file, you can choose the initial U-Boot environment through CONFIG_EXTRA_ENV_SETTINGS, including the boot command.

A generic configuration file is provided for each family:

For STMicroelectronics boards in OpenSTLinux, some configuration (bootcmd) are modified with CONFIG_SYS_CONFIG_NAME =

These STMicroelectronics configuration files can be:

  • either used in your project without mofiication (through CONFIG_SYS_CONFIG_NAME="stm32mp13_common.h", "stm32mp13_st_common.h", "stm32mp15_common.h" or " stm32mp15_st_common.h"), or
  • included in your board configuration file (e.g. #include "stm32mp13_common.h") before to override them or
  • used a starting point for your configuration file (copy and update it).

6 Configuration example[edit]

6.1 MTD partitions[edit]

In U-Boot, all the mtd fixed partitions are managed in U-Boot device tree based on the binding defined in Linux kernel file Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml .

For example in arch/arm/dts/stm32mp157c-ev1-u-boot.dtsi with:

&flash0 {
	partitions {
		compatible = "fixed-partitions";
		#address-cells = <1>;
		#size-cells = <1>;

		partition@0 {
			label = "fsbl1";
			reg = <0x00000000 0x00040000>;
		};
		partition@40000 {
			label = "fsbl2";
			reg = <0x00040000 0x00040000>;
		};
		partition@80000 {
			label = "metadata1";
			reg = <0x00080000 0x00040000>;
		};
		partition@c0000 {
			label = "metadata2";
			reg = <0x000c0000 0x00040000>;
		};
		partition@100000 {
			label = "fip-a";
			reg = <0x00100000 0x00400000>;
		};
		partition@500000 {
			label = "fip-b";
			reg = <0x00500000 0x00400000>;
		};
		partition@900000 {
			label = "u-boot-env";
			reg = <0x00900000 0x00080000>;
		};
		partition@980000 {
			label = "nor-user";
			reg = <0x00980000 0x03680000>;
		};
	};
};
&nand {
	partitions {
		compatible = "fixed-partitions";
		#address-cells = <1>;
		#size-cells = <1>;

		partition@0 {
			label = "fsbl1";
			reg = <0x00000000 0x00080000>;
		};
		partition@80000 {
			label = "fsbl2";
			reg = <0x00080000 0x00080000>;
		};
		partition@100000 {
			label = "metadata1";
			reg = <0x00100000 0x00080000>;
		};
		partition@180000 {
			label = "metadata2";
			reg = <0x00180000 0x00080000>;
		};
		partition@200000 {
			label = "fip-a1";
			reg = <0x00200000 0x00400000>;
		};
		partition@600000 {
			label = "fip-a2";
			reg = <0x00600000 0x00400000>;
		};
		partition@a00000 {
			label = "fip-b1";
			reg = <0x00a00000 0x00400000>;
		};
		partition@e00000 {
			label = "fip-b2";
			reg = <0x00e00000 0x00400000>;
		};
		partition@1200000 {
			label = "UBI";
			reg = <0x01200000 0x3ee00000>;
		};
	};
};

The customer can modify the MTD in U-Boot device tree for its board.

Warning white.png Warning
Other U-Boot configurations depend on the offset of MTD partition.

E.g for STM32MP1 series, the offset of U-Boot ENV in NOR named "u-boot-env" is align with

  • CONFIG_ENV_SECT_SIZE 0x40000, aligned with the maximum supported erase block for NOR, 256 Kbytes
  • CONFIG_ENV_OFFSET 0x900000, offset of ENV partition in NOR
  • CONFIG_ENV_OFFSET_REDUND 0x940000, offset of the second 'sector' in the ENV partition

U-Boot dynamically update the Linux® kernel device tree with these information with call fdt_copy_fixed_partitions() under CONFIG_OF_BOARD_SETUP in board/st/stm32mp1/stm32mp1.c ::ft_board_setup().

This device tree update enables the alignment of MTD configuration between U-Boot and Linux, and avoids STM32CubeProgrammer support issues as the MTD partition sizes has to be aligned with Flashlayout.

To define the MTD partitions in Linux device tree, no more call fdt_copy_fixed_partitions() in your board code or deactivate CONFIG_OF_BOARD_SETUP in the customer defconfig. However this might result in misalignment with U-Boot.

For information, you can also define the MTD configuration directly through this U-Boot configuration

  • CONFIG_MTDPARTS_DEFAULT and CONFIG_MTDIDS_DEFAULT
  • or by directly setting variable CONFIG_EXTRA_ENV_SETTINGS in your board configuration file:
    • mtdparts="mtdparts=nand0:2m(fsbl),4m(fip1),4m(fip2),-(UBI)"
    • mtdids="nand0=nand0"

This corresponds to a generic U-Boot configuration (see U-Boot documentation for additional details).

6.2 U-Boot memory mapping[edit]

The memory used by U-Boot is defined by several configurations.

6.2.1 Before relocation[edit]

Configuration is defined by Kconfig defines:

  • CONFIG_SYS_TEXT_BASE: Load Address of U-Boot, aligned with TF-A configuration (see STM32MP_BL33_BASE in TF-A FW config)
  • CONFIG_CUSTOM_SYS_INIT_SP_ADDR: Start for stack (reverse order)
  • CONFIG_PRE_CON_BUF_ADDR and CONFIG_PRE_CON_BUF_SZ (4096): PreConsole buffer
  • CONFIG_BOOTSTAGE_STASH_ADDR: bootstage stash buffer for SPL
  • CONFIG_SYS_MALLOC_F_LEN: reserved memory for alloc in STACK

The beginning of the DDR is mapped, limited by CONFIG_DDR_CACHEABLE_SIZE to avoid overlap with OP-TEE reserved memory, and used by U-Boot.

If you change the default configurations in your board defconfig file, you need to avoids overlap, particularly for stack and OP-TEE. The default values, used for Microelectronics boards, are defined:

Address Comment Config
C3000000 Bootstage CONFIG_BOOTSTAGE_STASH_ADDR
C0800000 PreConsole CONFIG_PRE_CON_BUF_ADDR + CONFIG_PRE_CON_BUF_SZ
C0400000 start for stack CONFIG_CUSTOM_SYS_INIT_SP_ADDR including CONFIG_SYS_MALLOC_F_LEN
C0000000 Load Address of U-Boot CONFIG_SYS_TEXT_BASE
Address Comment Config
C3000000 Bootstage CONFIG_BOOTSTAGE_STASH_ADDR
C02FF000 PreConsole CONFIG_PRE_CON_BUF_ADDR + CONFIG_PRE_CON_BUF_SZ
C0100000 Load Address of U-Boot CONFIG_SYS_TEXT_BASE
C0100000
C0000000
Stack (reverse order) CONFIG_CUSTOM_SYS_INIT_SP_ADDR including CONFIG_SYS_MALLOC_F_LEN,
limited by start of DDR

6.2.2 After relocation[edit]

U-Boot is reloaded at the end of the DDR, where it found enough available memory to its code and other reserved memory in common/board_r.c , e.g CONFIG_SYS_MALLOC_LEN and framebuffer.

The relocation address can be checked with bdinfo command in U-Boot console.

The size of DDR is automatically computed from DDRCTRL configuration with ADDRMAP1-6 registers (see stm32mp1_ddr_size() in drivers/ram/stm32mp1/stm32mp1_ram.c and the reserved-memory nodes present in its device tree are preserved by U-Boot (see board_get_usable_ram_top() in arch/arm/mach-stm32mp/dram_init.c ).

To avoid U-Boot violation access, the secure memory used OP-TEE needs to be aligned with OP-TEE reserved memory nodes in U-Boot device tree for your board device tree, for example arch/arm/dts/stm32mp135f-dk.dts :

 optee@de000000 {
 	reg = <0xde000000 0x2000000>;
 	no-map;
 };

The beginning of DDR is used by U-Boot commands (bootm for example) and scripts (DISTRO) as defined with variables in U-Boot environment or config:

  • CONFIG_SYS_LOAD_ADDR=0xc2000000, used by some U-Boot commands.
  • kernel_addr_r=0xc2000000
  • fdt_addr_r=0xc4000000
  • scriptaddr=0xc4100000
  • pxefile_addr_r=0xc4200000
  • fdtoverlay_addr_r=0xc4300000
  • ramdisk_addr_r=0xc4400000

These default values, define in generic configuration files, allow to load 32MB kernel or FIT (uncompressed/compressed), 1MB device tree file (fdt), 1MB script, 1MB pxe file and 1MB for overlay file and the ramdisk at the end. The kernel is loaded at its final location, normally 0xC0000000, by bootm command.

You can change these value in the #Configuration_file for your board to allow bigger files or optimized loading address, e.g. without relocation with fdt_high=0xFFFFFFFF or load kernel at a final location (see zImage in arm/booting.html).

See U-Boot documentation for details on these variables: usage/environment.html (v2022.10).

7 References[edit]