deleted>Frq08988 mNo edit summary |
Registered User m (remove spaces) |
||
(18 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
== Debug with console == | == Debug with console == | ||
Trace and error are available on the console defined in the '''chosen''' node of the device tree by the '''stdout-path''' field: | Trace and error are available on the console defined in the '''chosen''' node of the device tree by the '''stdout-path''' field, for example on serial0=uart4: | ||
chosen { | chosen { | ||
stdout-path = " | stdout-path = " {{Highlight|serial0}}:115200n8"; | ||
}; | |||
aliases { | |||
{{Highlight|serial0}} = &{{Highlight|uart4}}; | |||
}; | }; | ||
Line 31: | Line 24: | ||
or, | or, | ||
* activate the debug UART feature: | * activate the debug UART feature: | ||
** | ** add in defconfig of [[U-Boot_overview#U-Boot_configuration|U-Boot configuration]] | ||
** board_debug_uart_init(): | *** {{Highlight|CONFIG_DEBUG_UART}} | ||
*** {{Highlight|CONFIG_DEBUG_UART_STM32}} | |||
** adpat the function {{Highlight|board_debug_uart_init()}}: that configures the required resources (pad, clock) before initialization by the U-Boot driver.<br/>This function needs to be adapted for your board. | |||
== Debug with GDB | == Debug with GDB == | ||
With OpenSTLinux, you can directly use GDB script Setup.gdb: | |||
* [[GDB#U-Boot_execution_phase]] | |||
* [[GDB#U-Boot_boot_case]] | |||
Or for manual GDB connection, you need to: | |||
# get the [[U-Boot_overview#Output_files|elf files]] for U-Boot and/or SPL<br/>(u-boot and u-boot-spl available in the build directory) | |||
# connect [[GDB]] to the target | # connect [[GDB]] to the target | ||
# load the symbols of the binary to be debugged | # '''reset with attach''' the target with the gdb {{Highlight|"monitor reset halt"}} command:<br/>execution is stopped in ROM code or at the beginning of FSBL execution. | ||
# | # load the symbols of the binary to be debugged with commands available in next chapter:<br/>[[#Load U-Boot symbol]], [[#Load SPL symbol]], [[#Load SPL code and debug]] | ||
# start execution with the "continue" command | # start execution with the {{Highlight|"continue"}} command | ||
=== | === Load U-Boot symbol === | ||
With [[U-Boot_overview#U-Boot_phases|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 {{Highlight|"symbol-file"}} command: | |||
{{GDB$}} {{Highlight|symbol-file u-boot}} | |||
* After relocation with {{Highlight|"add-symbol-file"}} command to relocate the symbol with the code offset = gd->relocaddr: | |||
{{GDB$}} symbol-file u-boot {{Highlight|--> only for "gd_t" definition}} | |||
{{GDB$}} set $offset = ((gd_t *)$r9)->relocaddr {{Highlight|--> get relocation offset}} | |||
{{GDB$}} symbol-file {{Highlight|--> clear previous symbol }} | |||
{{GDB$}} {{Highlight|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 {{Highlight|"monitor reset halt"}} command: | |||
{{GDB$}} thbreak *0xC0100000 | |||
{{GDB$}} commands | |||
> symbol-file u-boot | > symbol-file u-boot | ||
> thbreak relocate_code | > thbreak relocate_code | ||
Line 71: | Line 77: | ||
> end | > end | ||
This script uses a temporary hardware breakpoint {{Highlight|"thbreak"}} to load the symbol when U-Boot code is loaded in DDR by FSBL = TF-A or SPL at the U-Boot entry point (CONFIG_SYS_TEXT_BASE = 0xC0100000). | |||
It allows the symbol to be loaded only when code is executed to avoid DDR access before DDR initialization. | |||
=== Load SPL symbol === | |||
To debug SPL with GDB on a Flashed device, ROM code loads the binary and the GDB script just loads the SPL symbols: | |||
{{GDB$}} symbol-file u-boot-spl | |||
== Load code and debug | === Load SPL code and debug === | ||
Sometimes you need to debug SPL execution on an unprogrammed target (for example for board bring-up), so you can use GDB to load the SPL code in embedded RAM and execute it. | |||
When execution is stopped in ROM code, you need to execute the {{Highlight|"load"}} commands, depending on the compilation flags defined in [[U-Boot_overview#Device_tree|U-Boot device tree]] to load the SPL code and the associated device tree: | |||
* CONFIG_OF_SEPARATE = dtb appended at the end of the code, not present in the elf file | * CONFIG_OF_SEPARATE = dtb appended at the end of the code, not present in the elf file (default configuration) | ||
{{GDB$}} file u-boot-spl | |||
{{GDB$}} load | |||
{{GDB$}} set $dtb = __bss_end | |||
{{GDB$}} restore spl/dt.dtb binary $dtb | |||
* CONFIG_OF_EMBED = dtb embedded in the elf file | * CONFIG_OF_EMBED = dtb embedded in the elf file (debug configuration) | ||
{{GDB$}} file u-boot-spl | |||
(gdb | {{GDB$}} load | ||
=== Debug the first SPL instructions === | |||
Sometime the SPL code execution is stopped by the gdb command "monitor reset halt" after the first instructions. | |||
To debug this part, you can modify the code: add a infinite loop in SPL code to wait the gdb connection. | |||
For example in {{CodeSource | U-Boot | arch/arm/mach-stm32mp/spl.c}} : | |||
<syntaxhighlight lang="c"> | |||
void board_init_f(ulong dummy) | |||
{ | |||
struct udevice *dev; | |||
int ret; | |||
/* volatile is needed to avoid gcc optimization */ | |||
volatile int stop = 0; | |||
/* infinite debug loop */ | |||
while ( !stop ) ; | |||
arch_cpu_init(); | |||
</syntaxhighlight> | |||
when gdb is attached and the SPL symbols are loaded, the infinite loop is interrupted by : | |||
{{GDB$}} set var stop=1 | |||
And you can debug the SPL first instruction by gdb commands. | |||
<noinclude> | |||
[[Category:U-Boot]] | |||
[[Category:Tracing tools]] | |||
[[Category:Debugging tools]] | |||
{{PublicationRequestId | 12894 | 2019-08-01}} | |||
</noinclude> |
Latest revision as of 08:46, 3 October 2019
1. Debug with console
Trace and error are available on the console defined in the chosen node of the device tree by the stdout-path field, for example on serial0=uart4:
serial0:115200n8"; }; aliases { serial0 = &uart4; };chosen { stdout-path = "
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
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
- adpat 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.
- add in defconfig of U-Boot configuration
2. Debug with GDB
With OpenSTLinux, you can directly use GDB script Setup.gdb:
Or for manual GDB connection, you need to:
- get the elf files for U-Boot and/or SPL
(u-boot and u-boot-spl available in the build directory) - connect GDB to the target
- 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. - load the symbols of the binary to be debugged with commands available in next chapter:
#Load U-Boot symbol, #Load SPL symbol, #Load SPL code and debug - start execution with the "continue" command
2.1. Load U-Boot symbol
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:
--> only for "gd_t" definition set $offset = ((gd_t *)$r9)->relocaddr --> get relocation offset symbol-file --> clear previous symbol add-symbol-file u-boot $offsetsymbol-file u-boot
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 or SPL at the U-Boot entry point (CONFIG_SYS_TEXT_BASE = 0xC0100000).
It allows the symbol to be loaded only when code is executed to avoid DDR access before DDR initialization.
2.2. Load SPL symbol
To debug SPL with GDB on a Flashed device, ROM code loads the binary and the GDB script just loads the SPL symbols:
symbol-file u-boot-spl
2.3. Load SPL code and debug
Sometimes you need to debug SPL execution on an unprogrammed target (for example for board bring-up), so you can use GDB to load the SPL code in embedded RAM and execute it.
When execution is stopped in ROM code, you need to execute the "load" commands, depending on the compilation flags defined in U-Boot device tree to load the SPL code and the associated device tree:
- CONFIG_OF_SEPARATE = dtb appended at the end of the code, not present in the elf file (default configuration)
file u-boot-spl
load
set $dtb = __bss_end
restore spl/dt.dtb binary $dtb
- CONFIG_OF_EMBED = dtb embedded in the elf file (debug configuration)
file u-boot-spl
load
2.4. Debug the first SPL instructions
Sometime the SPL code execution is stopped by the gdb command "monitor reset halt" after the first instructions.
To debug this part, you can modify the code: add a infinite loop in SPL code to wait the gdb connection.
For example in arch/arm/mach-stm32mp/spl.c :
void board_init_f(ulong dummy)
{
struct udevice *dev;
int ret;
/* volatile is needed to avoid gcc optimization */
volatile int stop = 0;
/* infinite debug loop */
while ( !stop ) ;
arch_cpu_init();
when gdb is attached and the SPL symbols are loaded, the infinite loop is interrupted by :
set var stop=1
And you can debug the SPL first instruction by gdb commands.