[PATCH 18/27] efi: Provide an easy way to debug with gdb
Simon Glass
sjg at chromium.org
Wed May 28 10:24:44 CEST 2025
Add a Kconfig option to easily enable debugging of the app using the
recommended method. Provide some docs too.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
doc/develop/uefi/u-boot_on_efi.rst | 39 ++++++++++++++++++++++++++++++
lib/efi_client/Kconfig | 12 ++++++++-
lib/efi_client/efi.c | 36 +++++++++++++++++++++++++++
3 files changed, 86 insertions(+), 1 deletion(-)
diff --git a/doc/develop/uefi/u-boot_on_efi.rst b/doc/develop/uefi/u-boot_on_efi.rst
index f1f9113b01f..d20d5b00ec6 100644
--- a/doc/develop/uefi/u-boot_on_efi.rst
+++ b/doc/develop/uefi/u-boot_on_efi.rst
@@ -338,6 +338,45 @@ Additionally something like (sda is assumed as disk device):
append root=/dev/sda2 console=tty0 console=ttyS0,115200n8 rootwait rw
+Debugging
+---------
+
+Debugging the app is not straightforward since it is relocated by the UEFI
+firmware before it is run.
+
+See
+`Debugging UEFI applications with GDB <https://wiki.osdev.org/Debugging_UEFI_applications_with_GDB>`_
+for details.
+
+Within U-Boot, enable `CONFIG_EFI_APP_DEBUG` which will cause U-Boot to write
+deadbeef to address `10000` which you can catch with gdb.
+
+In gdb the procedure is something like this, for a 64-bit machine::
+
+ # Enable CONFIG_EFI_APP_DEBUG in the build
+ $ grep CONFIG_EFI_APP_DEBUG .config
+ CONFIG_EFI_APP_DEBUG=y
+
+ $ gdb u-boot
+ # Connect to the target; here we assume 'qemu -Ss' has been started
+ (gdb) target remote localhost:1234
+
+ # Set a watchpoint for the marker write
+ (gdb) watch *(unsigned long *)0x10000 == 0xdeadbeef
+ (gdb) continue
+
+ # Execution will break as soon as the marker is written.
+ # Now, fetch the relocated base address:
+ (gdb) set $base = *(unsigned long long *)0x10008
+ (gdb) add-symbol-file u-boot -o $base
+
+ # Now you can set other breakpoints as needed
+
+For a 32-bit machine, use `unsigned long` for the cast when setting `$base`
+
+The address of 0x10000 is defined by `GDB_ADDR` which you can change in the
+code if needed.
+
Future work
-----------
diff --git a/lib/efi_client/Kconfig b/lib/efi_client/Kconfig
index fec5b7e004c..7ac6497ec09 100644
--- a/lib/efi_client/Kconfig
+++ b/lib/efi_client/Kconfig
@@ -70,9 +70,10 @@ config EFI_STUB_64BIT
endchoice
+if EFI_APP
+
config EFI_RAM_SIZE
hex "Amount of EFI RAM for U-Boot"
- depends on EFI_APP
default 0x10000000
help
Set the amount of EFI RAM which is claimed by U-Boot for its own
@@ -80,4 +81,13 @@ config EFI_RAM_SIZE
other smaller amounts) and it can never be increased after that.
It is used as the RAM size in with U-Boot.
+config EFI_APP_DEBUG
+ bool "Enable GDB debugging"
+ help
+ Enable this to allow GDB to stop the app at an early stage, so it is
+ possible to set the symbol offset. Since the app is relocated to an
+ unknown address, breakpoints will only work if this is done.
+
+endif # EFI_APP
+
endmenu
diff --git a/lib/efi_client/efi.c b/lib/efi_client/efi.c
index bb1d9e24f84..8b825c7a66e 100644
--- a/lib/efi_client/efi.c
+++ b/lib/efi_client/efi.c
@@ -18,6 +18,31 @@
#include <efi.h>
#include <efi_api.h>
+enum {
+ /* magic number to trigger gdb breakpoint */
+ GDB_MAGIC = 0xdeadbeef,
+
+ /* breakpoint address */
+ GDB_ADDR = 0x10000,
+};
+
+/**
+ * struct gdb_marker - structure to simplify debugging with gdb
+ *
+ * This struct is placed in memory and accessed to trigger a breakpoint in
+ * gdb.
+ *
+ * @magic: Magic number (GDB_MAGIC)
+ * @base: Base address of the app
+ */
+struct gdb_marker {
+ union {
+ u32 magic;
+ u64 space;
+ };
+ void *base;
+};
+
static struct efi_priv *global_priv;
struct efi_priv *efi_get_priv(void)
@@ -116,6 +141,17 @@ int efi_init(struct efi_priv *priv, const char *banner, efi_handle_t image,
priv->loaded_image = loaded_image;
priv->image_data_type = loaded_image->image_data_type;
+ if (IS_ENABLED(CONFIG_EFI_APP_DEBUG)) {
+ struct gdb_marker *marker = (struct gdb_marker *)GDB_ADDR;
+ char buf[64];
+
+ marker->base = priv->loaded_image->image_base;
+ snprintf(buf, sizeof(buf), "\ngdb marker at %p base %p\n",
+ marker, marker->base);
+ efi_puts(priv, buf);
+ marker->magic = 0xdeadbeef;
+ }
+
return 0;
}
--
2.43.0
More information about the U-Boot
mailing list