“U-Boot - How to debug”的版本间的差异

来自百问网嵌入式Linux wiki
第31行: 第31行:
 
== Debug with GDB ==
 
== Debug with GDB ==
  
With OpenSTLinux,  you can directly use GDB script Setup.gdb:
+
在OpenSTLinux中,可以直接使用GDB脚本Setup.gdb:
 
* [[GDB#U-Boot_execution_phase]]
 
* [[GDB#U-Boot_execution_phase]]
 
* [[GDB#U-Boot_boot_case]]
 
* [[GDB#U-Boot_boot_case]]
  
Or for manual GDB connection, you need to:
+
或者对于手动GDB连接,您需要:
# 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)
+
# 获取U-Boot和/或SPL的[[U-Boot_overview#Output_files|elf files]] <br/>(构建目录中提供了u-boot和u-boot-spl)
# connect [[GDB]] to the target
+
# [[GDB]]连接到目标
# '''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.
+
# 使用 gdb{{Highlight|"monitor reset halt"}}命令'''reset with attach'''复位目标:<br/>在ROM代码中或在FSBL执行开始时停止执行。
# 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]]
+
# 加载二进制文件的符号,以便在下一章中用可用的命令进行调试:<br/>[[#Load U-Boot symbol]], [[#Load SPL symbol]],  [[#Load SPL code and debug]]
# start execution with the {{Highlight|"continue"}} command
+
# 使用 {{Highlight|"continue"}} 命令开始执行。
  
 
=== Load U-Boot symbol ===
 
=== Load U-Boot symbol ===
  
With [[U-Boot_overview#U-Boot_phases|U-Boot relocation]], symbols are more difficult to load.
+
使用[[U-Boot_overview#U-Boot_phases|U-Boot relocation]]时,符号更难加载。
  
See https://www.denx.de/wiki/DULG/DebuggingUBoot
+
请参阅 https://www.denx.de/wiki/DULG/DebuggingUBoot
  
If you connect GDB on running target, you can load the debug symbols:
+
如果在运行的目标上连接GDB,则可以加载调试符号:
  
* Before relocation with {{Highlight|"symbol-file"}} command:
+
* 在使用 {{Highlight|"symbol-file"}} 命令进行重定位之前:
 
   {{GDB$}} {{Highlight|symbol-file u-boot}}
 
   {{GDB$}} {{Highlight|symbol-file u-boot}}
  
* After relocation with {{Highlight|"add-symbol-file"}} command to relocate the symbol with the code offset = gd->relocaddr:
+
* 使用{{Highlight|"add-symbol-file"}} 命令重定位后,使用代码 offset = gd->relocaddr 重定位该符号:
 
   {{GDB$}} symbol-file u-boot                            {{Highlight|--> only for "gd_t" definition}}
 
   {{GDB$}} symbol-file u-boot                            {{Highlight|--> only for "gd_t" definition}}
 
   {{GDB$}} set $offset = ((gd_t *)$r9)->relocaddr        {{Highlight|--> get relocation offset}}
 
   {{GDB$}} set $offset = ((gd_t *)$r9)->relocaddr        {{Highlight|--> get relocation offset}}
第59行: 第59行:
 
   {{GDB$}} {{Highlight|add-symbol-file u-boot $offset}}
 
   {{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示例脚本在{{Highlight|"monitor reset halt"}} 命令之后,在为编程板重定位前后自动加载U-Boot符号:
  
 
   {{GDB$}} thbreak *0xC0100000
 
   {{GDB$}} thbreak *0xC0100000
第77行: 第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).
+
当通过U-Boot入口点(CONFIG_SYS_TEXT_BASE = 0xC0100000)处的FSBL=TF-A或SPL将U-Boot代码加载到DDR中时,此脚本使用临时硬件断点{{Highlight|"thbreak"}} 加载符号。
 
+
它只允许在执行代码时加载符号,以避免在DDR初始化之前访问DDR。
It allows the symbol to be loaded only when code is executed to avoid DDR access before DDR initialization.
 
 
 
 
=== Load SPL symbol ===
 
=== 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调试SPL,ROM代码加载二进制文件,GDB脚本只加载SPL符号:
  
 
   {{GDB$}} symbol-file u-boot-spl
 
   {{GDB$}} symbol-file u-boot-spl
第89行: 第87行:
 
=== Load SPL 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.
+
有时,您需要在未编程的目标上调试SPL执行(例如,用于电路板启动),因此您可以使用GDB将SPL代码加载到嵌入式RAM中并执行。
  
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:
+
在ROM代码中停止执行时,您需要执行{{Highlight|"load"}}命令,具体取决于 [[U-Boot_overview#Device_tree|U-Boot device tree]] 中定义的编译标志来加载SPL代码和关联的设备树:
  
* CONFIG_OF_SEPARATE = dtb appended at the end of the code, not present in the elf file (default configuration)
+
* CONFIG_OF_SEPARATE = dtb 附加在代码末尾,不存在于elf文件中(默认配置)
  
 
   {{GDB$}} file u-boot-spl
 
   {{GDB$}} file u-boot-spl
第100行: 第98行:
 
   {{GDB$}} restore spl/dt.dtb binary $dtb
 
   {{GDB$}} restore spl/dt.dtb binary $dtb
  
* CONFIG_OF_EMBED = dtb embedded in the elf file (debug configuration)
+
* CONFIG_OF_EMBED = dtb 嵌入elf文件中(调试配置)
  
 
   {{GDB$}} file u-boot-spl
 
   {{GDB$}} file u-boot-spl
第107行: 第105行:
 
=== Debug the first SPL instructions ===
 
=== Debug the first SPL instructions ===
  
Sometime the SPL code execution is stopped by the gdb command "monitor reset halt" after the first instructions.
+
有时,在第一条指令之后,gdb命令 "monitor reset halt" 会停止SPL代码的执行。
  
To debug this part, you can modify the code: add a infinite loop in SPL code to wait the gdb connection.
+
要调试这部分代码,可以修改代码:在SPL代码中添加一个无限循环以等待gdb连接。
  
For example in {{CodeSource | U-Boot | arch/arm/mach-stm32mp/spl.c}} :
+
例如,在{{CodeSource | U-Boot | arch/arm/mach-stm32mp/spl.c}}:
  
 
<syntaxhighlight lang="c">
 
<syntaxhighlight lang="c">
第127行: 第125行:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
when gdb is attached and the SPL symbols are loaded, the infinite loop is interrupted by :
+
当连接gdb并加载SPL符号时,无限循环会因以下原因中断:
  
 
   {{GDB$}} set var stop=1
 
   {{GDB$}} set var stop=1
  
And you can debug the SPL first instruction by gdb commands.
+
您可以通过gdb命令调试SPL first指令。
 
 
 
<noinclude>
 
<noinclude>
 
[[Category:U-Boot]]
 
[[Category:U-Boot]]

2020年11月3日 (二) 15:07的版本

Debug with console

跟踪和错误在设备树的chosen 节点中通过 stdout-path 字段定义的控制台上可用,例如在serial0 = uart4上:

 chosen {
 	stdout-path = " serial0:115200n8";
 };
 aliases {
 	serial0 = &uart4;
 };

默认情况下,U-Boot使用的宏 (debug(), pr_debug()...)不打印任何跟踪;要激活特定文件上的调试跟踪,需要启用 DEBUG 编译标志并更改文件的LOGLEVEL:

  • 在<file>.c文件包含任何之前定义调试
 #define DEBUG
 #undef CONFIG_LOGLEVEL
 #define CONFIG_LOGLEVEL 8
  • 使用 Makefile
 CFLAGS_<file>.o+= -DDEBUG -DCONFIG_LOGLEVEL=8

如果在配置控制台之前(在执行U-Boot的第一阶段)U-Boot失败,则跟踪不可用。

在这种情况下,您需要:

  • 用GDB调试 (请参阅下一章)

或,

  • 激活调试UART功能:
    • U-Boot configuration的defconfig中添加
      • CONFIG_DEBUG_UART
      • CONFIG_DEBUG_UART_STM32
    • adpat 这个函数 board_debug_uart_init(): 在通过U-Boot驱动程序初始化之前配置所需的资源 (pad, clock)。
      此功能需要针对您的主板进行调整。

Debug with GDB

在OpenSTLinux中,可以直接使用GDB脚本Setup.gdb:

或者对于手动GDB连接,您需要:

  1. 获取U-Boot和/或SPL的elf files
    (构建目录中提供了u-boot和u-boot-spl)
  2. GDB连接到目标
  3. 使用 gdb"monitor reset halt"命令reset with attach复位目标:
    在ROM代码中或在FSBL执行开始时停止执行。
  4. 加载二进制文件的符号,以便在下一章中用可用的命令进行调试:
    #Load U-Boot symbol, #Load SPL symbol, #Load SPL code and debug
  5. 使用 "continue" 命令开始执行。

Load U-Boot symbol

使用U-Boot relocation时,符号更难加载。

请参阅 https://www.denx.de/wiki/DULG/DebuggingUBoot

如果在运行的目标上连接GDB,则可以加载调试符号:

  • 在使用 "symbol-file" 命令进行重定位之前:
 (gdb) symbol-file u-boot
  • 使用"add-symbol-file" 命令重定位后,使用代码 offset = gd->relocaddr 重定位该符号:
 (gdb) symbol-file u-boot                            --> only for "gd_t" definition
 (gdb) set $offset = ((gd_t *)$r9)->relocaddr        --> get relocation offset
 (gdb) symbol-file                                   --> clear previous symbol 
 (gdb) add-symbol-file u-boot $offset

以下GDB示例脚本在"monitor reset halt" 命令之后,在为编程板重定位前后自动加载U-Boot符号:

 (gdb) thbreak *0xC0100000
 (gdb) 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

当通过U-Boot入口点(CONFIG_SYS_TEXT_BASE = 0xC0100000)处的FSBL=TF-A或SPL将U-Boot代码加载到DDR中时,此脚本使用临时硬件断点"thbreak" 加载符号。 它只允许在执行代码时加载符号,以避免在DDR初始化之前访问DDR。

Load SPL symbol

要在闪存设备上使用GDB调试SPL,ROM代码加载二进制文件,GDB脚本只加载SPL符号:

 (gdb) symbol-file u-boot-spl

Load SPL code and debug

有时,您需要在未编程的目标上调试SPL执行(例如,用于电路板启动),因此您可以使用GDB将SPL代码加载到嵌入式RAM中并执行。

在ROM代码中停止执行时,您需要执行"load"命令,具体取决于 U-Boot device tree 中定义的编译标志来加载SPL代码和关联的设备树:

  • CONFIG_OF_SEPARATE = dtb 附加在代码末尾,不存在于elf文件中(默认配置)
 (gdb) file u-boot-spl
 (gdb) load
 (gdb) set $dtb =  __bss_end
 (gdb) restore spl/dt.dtb binary $dtb
  • CONFIG_OF_EMBED = dtb 嵌入elf文件中(调试配置)
 (gdb) file u-boot-spl
 (gdb) load

Debug the first SPL instructions

有时,在第一条指令之后,gdb命令 "monitor reset halt" 会停止SPL代码的执行。

要调试这部分代码,可以修改代码:在SPL代码中添加一个无限循环以等待gdb连接。

例如,在arch/arm/mach-stm32mp/spl.c| |}} 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();

当连接gdb并加载SPL符号时,无限循环会因以下原因中断:

 (gdb) set var stop=1

您可以通过gdb命令调试SPL first指令。 <securetransclude src="ProtectedTemplate:PublicationRequestId" params="12894 | 2019-08-01 |"></securetransclude>