blob: 4e359c7f226468e365d507da8a5126c8f01681c4 [file] [log] [blame]
Alexander Dahle2764002024-06-26 12:47:18 +02001.. SPDX-License-Identifier: GPL-2.0+
2.. Copyright (c) 2024 Alexander Dahl
3
4Debugging U-Boot with GDB
5=========================
6
7Using a JTAG adapter it is possible to debug a running U-Boot with GDB.
8A common way is to connect a debug adapter to the JTAG connector of your
9board, run a GDB server, connect GDB to the GDB server, and use GDB as usual.
10
11Similarly QEMU can provide a GDB server.
12
13Preparing build
14---------------
15
16Building U-Boot with with reduced optimization (-Og) and without link time
17optimization is recommended for easier debugging::
18
19 CONFIG_CC_OPTIMIZE_FOR_DEBUG=y
20 CONFIG_LTO=n
21
22Otherwise build, install, and run U-Boot as usual.
23
24Using OpenOCD as GDB server
25---------------------------
26
27`OpenOCD <https://openocd.org/>`_ is an open source tool supporting hardware
28debug probes, and providing a GDB server. It is readily available in major Linux
29distributions or you can build it from source.
30
31Here is example of starting OpenOCD on Debian using a J-Link adapter and a
32board with an AT91 SAMA5D2 SoC:
33
34.. code-block:: console
35
36 $ openocd -f interface/jlink.cfg -f target/at91sama5d2.cfg -c 'adapter speed 4000'
37 Open On-Chip Debugger 0.12.0
38 Licensed under GNU GPL v2
39 For bug reports, read
40 http://openocd.org/doc/doxygen/bugs.html
41 Info : auto-selecting first available session transport "jtag". To override use 'transport select <transport>'.
42 adapter speed: 4000 kHz
43
44 Info : Listening on port 6666 for tcl connections
45 Info : Listening on port 4444 for telnet connections
46 Info : J-Link V10 compiled Jan 30 2023 11:28:07
47 Info : Hardware version: 10.10
48 Info : VTarget = 3.244 V
49 Info : clock speed 4000 kHz
50 Info : JTAG tap: at91sama5d2.cpu tap/device found: 0x5ba00477 (mfg: 0x23b (ARM Ltd), part: 0xba00, ver: 0x5)
51 Info : at91sama5d2.cpu_a5.0: hardware has 3 breakpoints, 2 watchpoints
52 Info : at91sama5d2.cpu_a5.0: MPIDR level2 0, cluster 0, core 0, mono core, no SMT
53 Info : starting gdb server for at91sama5d2.cpu_a5.0 on 3333
54 Info : Listening on port 3333 for gdb connections
55
56Notice that OpenOCD is listening on port 3333 for GDB connections.
57
58Using QEMU as GDB server
59------------------------
60
61When running U-Boot on QEMU you can used the '-gdb' parameter to provide a
62GDB server:
63
64 qemu-system-riscv64 -M virt -nographic -gdb tcp::3333 -kernel u-boot
65
66Running a GDB session
67----------------------
68
69You need a GDB suited for your target. This can be the GDB coming with your
70toolchain or *gdb-multiarch* available in your Linux distribution.
71
72.. prompt:: bash $
73
74 gdb-multiarch u-boot
75
76In the above command-line *u-boot* is the U-boot binary in your build
77directory. You may need to adjust the path when calling GDB.
78
79Connect to the GDB server like this:
80
81.. code-block:: console
82
83 (gdb) target extended-remote :3333
84 Remote debugging using :3333
85 0x27fa9ac6 in ?? ()
86 (gdb)
87
88This is fine for debugging before U-Boot relocates itself.
89
90For debugging U-Boot after relocation you need to indicate the relocation
91address to GDB. You can retrieve the relocation address from the U-Boot shell
92with the command *bdinfo*:
93
94.. code-block:: console
95
96 U-Boot> bdinfo
97 boot_params = 0x20000100
98 DRAM bank = 0x00000000
99 -> start = 0x20000000
100 -> size = 0x08000000
101 flashstart = 0x00000000
102 flashsize = 0x00000000
103 flashoffset = 0x00000000
104 baudrate = 115200 bps
105 relocaddr = 0x27f7a000
106 reloc off = 0x0607a000
107 Build = 32-bit
108 current eth = ethernet@f8008000
109 ethaddr = 00:50:c2:31:58:d4
110 IP addr = <NULL>
111 fdt_blob = 0x27b36060
112 new_fdt = 0x27b36060
113 fdt_size = 0x00003e40
114 lmb_dump_all:
115 memory.cnt = 0x1 / max = 0x10
116 memory[0] [0x20000000-0x27ffffff], 0x08000000 bytes flags: 0
117 reserved.cnt = 0x1 / max = 0x10
118 reserved[0] [0x27b31d00-0x27ffffff], 0x004ce300 bytes flags: 0
119 devicetree = separate
120 arch_number = 0x00000000
121 TLB addr = 0x27ff0000
122 irq_sp = 0x27b36050
123 sp start = 0x27b36040
124 Early malloc usage: cd8 / 2000
125
126Look out for the line starting with *relocaddr* which has the address
127you need, ``0x27f7a000`` in this case.
128
129On most architectures (not sandbox, x86, Xtensa) the global data pointer is
130stored in a fixed register:
131
132============ ========
133Architecture Register
134============ ========
135arc r25
136arm r9
137arm64 x18
138m68k d7
139microblaze r31
140mips k0
141nios2 gp
142powerpc r2
143riscv gp
144sh r13
145============ ========
146
147On these architecture the relocation address cat be determined by
148dereferencing the global data pointer stored in register, *r9* in the example:
149
150.. code-block:: console
151
152 (gdb) p/x (*(struct global_data*)$r9)->relocaddr
153 $1 = 0x27f7a000
154
155In the GDB shell discard the previously loaded symbol file and add it once
156again with the relocation address like this:
157
158.. code-block:: console
159
160 (gdb) symbol-file
161 Discard symbol table from `/home/adahl/build/u-boot/v2024.04.x/u-boot'? (y or n) y
162 No symbol file now.
163 (gdb) add-symbol-file u-boot 0x27f7a000
164 add symbol table from file "u-boot" at
165 .text_addr = 0x27f7a000
166 (y or n) y
167 Reading symbols from u-boot...
168 (gdb)
169
170You can now use GDB as usual, setting breakpoints, printing backtraces,
171inspecting variables, stepping through the code, etc.