efi: Provide an easy way to debug with gdb
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@chromium.org>
This commit is contained in:
@@ -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
|
||||
-----------
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user