Отладка образа GRUB2 EFI, запущенного на QEMU

Чего я хочу добиться

Я хочу настроить образ GRUB EFI и отлаживать его во время работы в QEMU.

Итак, я пытаюсь отладить ванильный образ GRUB перед его настройкой.

Что я сделал до сих пор

Я загрузил GRUB2 с http://git.savannah.gnu.org и скомпилировал его:

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

Затем сгенерировал тривиальное изображение EFI с:

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

И поместите его в файл образа диска:

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

Чтобы загрузить его, я скомпилировал IA32 OVMF.fd, чтобы использовать его с QEMU:

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

Он загружается правильно, давая мне оболочку grub.


Где я застрял

Теперь я хочу отладить GRUB. Поэтому я вызвал QEMU с дополнительными параметрами:

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

И прикрепил gdb к QEMU:

cd grub-core/
gdb -x gdb_grub

Однако кажется, что символы отладки отсутствуют:

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)

Что я делаю неправильно?


После добавления символов

@unixsmurf, похоже, загружает символы отладки, когда я использую команду symbol-file. Действительно, GDB говорит

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

Однако я все еще не могу выполнить команду next, которая возвращает

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

Я бы хотел, например, установить точку останова в функции grub_core/kern/main.c:grub_main и запускать ее шаг за шагом.

Но хотя точка останова установлена, когда я continue выполнение, GRUB достигает оболочки, не останавливаясь на точке останова:

(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.

person lseki    schedule 09.05.2017    source источник


Ответы (2)


В ваш bootIA32.efi образ не включены символы отладки. Сценарий gdb_grub пытается сделать это, но поскольку он был разработан для BIOS (не UEFI) и, по-видимому, в основном включен и сгенерирован в основном случайно, на самом деле он больше не работает, поскольку версия GRUB для EFI динамически направляется по адресу решил во время выполнения.

Теперь, с помощью небольшого обмана (и OVMF_CODE.fd, построенного с -D DEBUG_ON_SERIAL_PORT), я вижу, что, пока я не выполняю никаких других команд перед входом в GRUB, я всегда вижу:

Loading driver at 0x0003DDE9000 EntryPoint=0x0003DDE9400

Итак, с помощью ужасного взлома на gdb_grub, изменив строку ближе к концу:

file kernel.exec

to

add-symbol-file kernel.exec 0x0003DDE9400

Я получаю ситуацию вместо

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

После этого момента. И если я продолжу, загрузка символа модуля теперь работает так, как задумано скриптом:

(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

Не совсем готово к производству, но работоспособно.

person unixsmurf    schedule 10.05.2017
comment
Он все еще не позволяет мне отлаживать ... Я добавил в вопрос информацию о том, что произошло после загрузки kernel.exec - person lseki; 10.05.2017
comment
Итак, если копнуть глубже, эта функциональность явно была реализована до EFI, поэтому базовая функциональность здесь немного ... неуклюжая. Соответственно обновляя ответ. - person unixsmurf; 11.05.2017
comment
Большой! Сработало нормально :-) Думаю, вы имели в виду add-symbol-file kernel.exec 0x0003DDE9400. - person lseki; 15.05.2017
comment
Ах да, упс. Отредактировано. - person unixsmurf; 15.05.2017

Принятый ответ сработал для меня как волшебство.

Кстати, я использую следующий исполняемый файл нижнего уровня для создания EFI, как и для полного образа debian qemu (команда создает EFI меньшего размера и может быть запущена из любого каталога).

MODULES="search iso9660 configfile normal memdisk tar part_msdos part_gpt fat"
$GRUB_PATH/grub-mkimage -O x86_64-efi -d $GRUB_PATH/grub-core -p "" -o ./grub.efi $MODULES

Мне все еще нужно запустить сеанс gdb в том же исходном каталоге, что и kernel.exec, потому что пути к исходным файлам относятся к этому каталогу.

person dturvene    schedule 06.10.2020
comment
Список МОДУЛИ, который я использовал выше, является достаточным набором для загрузки. Для полной функциональности я вытащил все модули grub с помощью чего-то вроде (cd $ GRUB_PATH / grub-core; find. -Name * .mod) ›grubmods.lst, а затем использовал это для создания (гораздо большего) изображения. - person dturvene; 07.10.2020