Last edited 8 months ago

U-Boot - How to debug

The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

1. Debug with console[edit | edit source]

See U-Boot Documentation or doc/develop/logging.rst for U-Boot logging details.

CONFIG_LOG is enable in OpenSTLinux.

By default, traces are available on the U-Boot console which use stdout-path defined in the chosen node of the Linux kernel device tree as described in the Linux kernel binding[1].

See page How to configure U-Boot for your board for configuration details.

The ST boards use the default logging configuration:

  • CONFIG_LOG_DEFAULT_LEVEL = CONFIG_LOG_MAX_LEVEL = LOGL_INFO = 6
    the 'debug' macros used by U-Boot (log_debug(), debug(), pr_debug()...) are removed in the U-Boot binary.
  • CONFIG_LOGF_FILE, CONFIG_LOGF_LINE, CONFIG_LOGF_FUNC are not activated
    no debug information in log messages by default.

To enable all the debug traces in U-Boot you need to increase the max logging level with a major impact on U-Boot size; e.g. set CONFIG_LOG_MAX_LEVEL to LOGL_DEBUG by adding in your defconfig file the line:

 CONFIG_LOG_MAX_LEVEL=7

When the traces are present in U-Boot, you can change the default trace level with CONFIG_LOG_DEFAULT_LEVEL or you can use the log command (CONFIG_CMD_LOG) to dynamically configure and filter the output:

 log level 7
 log format all

1.1. Activate debug trace on one file[edit | edit source]

To turn on this debug logging just in one file, you can define LOG_DEBUG for this file

  • add define before any include in the <file>.c file
 #define LOG_DEBUG
 #include <common.h>
  • with a Makefile
 CFLAGS_<file>.o+= -DLOG_DEBUG

1.2. Debug before console[edit | edit source]

If U-Boot fails before the console configuration (in the first stage of U-Boot execution), trace is not available.

In this case, you need to:

  • debug with GDB (see the next chapter)

or,

  • activate the debug UART feature:

2. Debug with GDB[edit | edit source]

With OpenSTLinux, you can directly use GDB script Setup.gdb:

Or for manual GDB connection, you need to:

  1. get the elf files for U-Boot = u-boot available in the build directory
  2. connect GDB to the target
  3. reset with attach the target with the gdb "monitor reset halt" command:
    execution is stopped in ROM code or at the beginning of FSBL execution.
  4. load the symbols of the binary to be debugged with commands available in next chapter:
    #Load U-Boot symbol
  5. start execution with the "continue" command

2.1. Load U-Boot symbol[edit | edit source]

With U-Boot relocation, symbols are more difficult to load, see doc/README.arm-relocation for details.

If you connect GDB on running target, you can load the debug symbols:

  • Before relocation with "symbol-file" command:
 symbol-file u-boot
  • After relocation with "add-symbol-file" command to relocate the symbol with the code offset = gd->relocaddr:
  • for STM32MP1 series (AARCH32)
 symbol-file u-boot                            --> only for "gd_t" definition
 set $offset = ((gd_t *)$r9)->relocaddr        --> get relocation offset, gd in r9 register
 symbol-file                                   --> clear previous symbol 
 add-symbol-file u-boot $offset
  • for STM32MP2 series (AARCH64)
 symbol-file u-boot                            --> only for "gd_t" definition
 set $offset = ((gd_t *)$x18)->relocaddr       --> get relocation offset, gd in x18 register
 symbol-file                                   --> clear previous symbol 
 add-symbol-file u-boot $offset

The following GDB example scripts automatically loads the U-Boot symbol before and after relocation for a programmed board, after "monitor reset halt" command.

These GDB scripts use a temporary hardware breakpoint "thbreak" to load the symbol when U-Boot code is loaded in DDR by FSBL = TF-A at the U-Boot entry point, CONFIG_TEXT_BASE.
It allows the symbol to be loaded only when code is executed to avoid DDR access before DDR initialization.

  • for STM32MP1 series (AARCH32)
 thbreak *0xC0100000
 commands
 > symbol-file u-boot
 > thbreak relocate_code
 > commands
   > print "RELOCATE U-Boot..."
   > set $offset = ((gd_t *)$r9)->relocaddr
   > print $offset
   > symbol-file
   > add-symbol-file u-boot $offset
   > thbreak boot_jump_linux
   > continue
   > end
 > continue
 > end

With CONFIG_TEXT_BASE =

  • 0xC0000000 for STM32MP13x lines More info.png
  • 0xC0100000 for STM32MP15x lines More info.png
  • for STM32MP2 series (AARCH64)
 thbreak *0x84000000
 commands
 > symbol-file u-boot
 > thbreak relocate_code
 > commands
   > print "RELOCATE U-Boot..."
   > set $offset = ((gd_t *)$x18->relocaddr
   > print $offset
   > symbol-file
   > add-symbol-file u-boot $offset
   > thbreak boot_jump_linux
   > continue
   > end
 > continue
 > end

With CONFIG_TEXT_BASE =

  • 0x84000000 for STM32MP2 series

3. References[edit | edit source]

  1. dtschema/schemas/chosen.yaml the Linux kernel binding for chosen node