U-Boot - How to debug

Revision as of 12:01, 23 February 2022 by Registered User (remove SPL)
Applicable for STM32MP13x lines, STM32MP15x lines

1. Debug with console[edit source]

Trace and error 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.

By default, the macros used by U-Boot (debug(), pr_debug()...) do not print any trace; to activate the debug traces on a specific file, you need to enable the DEBUG compilation flag and change the LOGLEVEL for the file:

  • define DEBUG before any include in the <file>.c file
 #define DEBUG
 #undef CONFIG_LOGLEVEL
 #define CONFIG_LOGLEVEL 8
  • with a Makefile
 CFLAGS_<file>.o+= -DDEBUG -DCONFIG_LOGLEVEL=8

For details, see doc/README.log .

If you want to enable the DEBUG traces for all the source code, you have to :

  • edit your defconfig file and add the option:
  CONFIG_LOGLEVEL=8
  • edit the Makefile and add DEBUG=1 option on used CFLAGS with:
  KBUILD_CFLAGS += -D DEBUG=1

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:
    • add in defconfig of U-Boot configuration
      • CONFIG_DEBUG_UART
      • CONFIG_DEBUG_UART_STM32
    • adapt the function board_debug_uart_init(): that configures the required resources (pad, clock) before initialization by the U-Boot driver.
      This function needs to be adapted for your board.

2. Debug with GDB[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 source]

With U-Boot relocation, symbols are more difficult to load.

See https://www.denx.de/wiki/DULG/DebuggingUBoot

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:
  symbol-file u-boot                            --> only for "gd_t" definition
  set $offset = ((gd_t *)$r9)->relocaddr        --> get relocation offset
  symbol-file                                   --> clear previous symbol 
  add-symbol-file u-boot $offset

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

  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

This script uses 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_SYS_TEXT_BASE =

  • 0xC0000000 for STM32MP13x lines More info.png
  • 0xC0100000 for STM32MP15x lines More info.png

It allows the symbol to be loaded only when code is executed to avoid DDR access before DDR initialization.

3. References[edit source]

  1. Documentation/devicetree/bindings/chosen.txt the Linux kernel binding for chosen node