Debugging a GRUB2 EFI image running on QEMU

What i want to achieve

I want to customize the GRUB EFI image and debug it while running in QEMU.

So I'm trying to debug the vanilla GRUB image before setting it up.

What have I done so far

I downloaded GRUB2 from http://git.savannah.gnu.org and compiled it:

./autogen.sh
./configure --prefix=`pwd`/local --with-platform=efi --target=i386 CFLAGS=-g
make
make install

      

Then a trivial EFI image is generated with:

./local/bin/grub-mkstandalone -O i386-efi -o bootIA32.efi

      

And place it in your disk image file:

qemu-img create -f raw hda.img 1G
mkfs.fat hda.img
sudo mount -o uid=$UID hda.img /mnt
mkdir -p /mnt/efi/boot/
mv bootIA32.efi /mnt/efi/boot/
sudo umount /mnt

      

To download it, I compiled IA32 OVMF.fd to use it with QEMU:

qemu-system-i386 -bios $UDK_PATH/Build/OvmfIa32/RELEASE_GCC48/FV/OVMF.fd \
                 -hda hda.img

      

It boots correctly, giving me a grub shell.


Where i am stuck

Now I want to debug GRUB. Therefore, I called QEMU additional parameters:

qemu-system-i386 -bios $UDK_PATH/Build/OvmfIa32/RELEASE_GCC48/FV/OVMF.fd \
                 -hda hda.img \
                 -s -S

      

And attached gdb to QEMU:

cd grub-core/
gdb -x gdb_grub

      

However, it seems that the debug symbols are missing:

GNU gdb (Debian 7.7.1+dfsg-5) 7.7.1
(...)
For help, type "help".
Type "apropos word" to search for commands related to "word".
0x0000fff0 in grub_disk_cache_table ()
Breakpoint 1 at 0x49b1: file kern/dl.c, line 53.
(gdb) n
Single stepping until exit from function grub_disk_cache_table,
which has no line number information.
0xffffff75 in ?? ()
(gdb)

      

What am I doing wrong?


After adding symbols

@unixsmurf seems to load debug symbols when I use the command symbol-file

. Indeed gdb says

(gdb) symbol-file ../local/lib/grub/i386-efi/kernel.exec
Reading symbols from ../local/lib/grub/i386-efi/kernel.exec...done.

      

However, I still cannot execute the command next

that returns

(gdb) n
Single stepping until exit from function grub_disk_cache_table,
which has no line number information.
0xffffff75 in ?? ()

      

I would like, for example, to set a breakpoint at grub_core/kern/main.c:grub_main

and execute it step by step.

But although a breakpoint is set, when I continue

execute, GRUB reaches the shell without stopping at the breakpoint:

(gdb) b main.c:grub_main
Note: breakpoint 2 also set at pc 0x6082.
Breakpoint 3 at 0x6082: file kern/main.c, line 266.
(gdb) c
Continuing.

      

+3


source to share


1 answer


There bootIA32.efi

are no debug symbols in your image. gdb_grub

The script tries to do this, but since it was designed for BIOS (not UEFI) and seems to be mostly included and generated mostly by accident, this no longer works - as the GRUB EFI version is dynamically to an address determined at runtime.

Now, with a bit of trickery (and OVMF_CODE.fd

built with help -D DEBUG_ON_SERIAL_PORT

), I see that as long as I don't run any other commands before entering GRUB, I always see:

Loading driver at 0x0003DDE9000 EntryPoint=0x0003DDE9400

      

So, with a terrible hack gdb_grub

, changing the line towards the end:

file kernel.exec

      

to



add-symbol-file kernel.exec 0x0003DDE9400

      

I end up with a situation instead of

add symbol table from file "kernel.exec" at
.text_addr = 0x3dde9400
0x0000fff0 in ?? ()
Breakpoint 1 at 0x3ddedddb: file kern/dl.c, line 53.
(gdb)

      

After this point. And if I continue, loading the module symbol now works like a script:

(gdb) cont
Continuing.
add symbol table from file "memdisk.module" at
    .text_addr = 0x3bf75cb0
    .rodata.str1.1_addr = 0x3bf75e77
    .data_addr = 0x3bf75ee0
    .module_license_addr = 0x3bf75f00
    .bss_addr = 0x3bf75f10
add symbol table from file "archelp.module" at
    .text_addr = 0x3b885ef0
    .rodata.str1.1_addr = 0x3b8864d6
    .module_license_addr = 0x3b88653c

      

Not quite production-ready, but workable.

+3


source







All Articles