it-swarm.com.ru

Как отладить ядро ​​Linux с помощью GDB и QEMU?

Я новичок в разработке ядра, и я хотел бы знать, как запустить/отладить ядро ​​Linux, используя QEMU и gdb. На самом деле я читаю книгу Роберта Лава, но, к сожалению, она не помогает читателю в том, как установить надлежащие инструменты для запуска или отладки ядра ... Так что я сделал, следуя этому руководству http: //opensourceforu.efytimes .com/2011/02/kernel-development-debugging-using-Eclipse/ . Я использую Eclipse в качестве IDE для разработки на ядре, но сначала я хотел, чтобы он работал под QEMU/gdb. Итак, что я сделал до сих пор:

1) Скомпилировать ядро ​​с:

make defconfig (then setting the CONFIG_DEBUG_INFO=y in the .config)
make -j4

2) После завершения компиляции я запускаю Qemu, используя:

qemu-system-x86_64 -s -S /dev/zero -kernel /Arch/x86/boot/bzImage

которые запускают ядро ​​в "остановленном" состоянии

3) Таким образом, я должен использовать GDB, я пытаюсь следующую команду:

gdb ./vmlinux

который запускает его правильно, но ... Теперь я не знаю, что делать ... Я знаю, что я должен использовать удаленную отладку на порту 1234 (порт по умолчанию, используемый Qemu), используя vmlinux в качестве файла таблицы символов для отладки.

Поэтому мой вопрос: что я должен сделать, чтобы запустить ядро ​​в Qemu, подключить к нему мой отладчик и, таким образом, заставить их работать вместе, чтобы облегчить мою жизнь с разработкой ядра.

28
E-Kami

Я бы попробовал:

(gdb) target remote localhost:1234
(gdb) continue

Использование опции '-s' заставляет qemu прослушивать порт tcp :: 1234, к которому вы можете подключиться как localhost: 1234, если вы находитесь на той же машине. Опция '-S' в Qemu заставляет Qemu останавливать выполнение, пока вы не дадите команду продолжения.

Лучше всего было бы взглянуть на приличный учебник GDB, чтобы понять, что вы делаете. Этот выглядит довольно приятно.

24
BjoernD

Пошаговая процедура протестирована на хосте Ubuntu 16.10

Чтобы быстро начать с нуля, я сделал минимальный полностью автоматизированный пример QEMU + Buildroot по адресу: https://github.com/cirosantilli/linux-kernel-module-cheat/blob/c7bbc6029af7f4fab0a23a380d1607df0b2a3701/gdb-ugtep-. MD Основные шаги описаны ниже.

Сначала получите корневую файловую систему rootfs.cpio.gz. Если вам это нужно, подумайте:

Тогда на ядре Linux:

git checkout v4.15
make mrproper
make x86_64_defconfig
cat <<EOF >.config-fragment
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_KERNEL=y
CONFIG_GDB_SCRIPTS=y
EOF
./scripts/kconfig/merge_config.sh .config .config-fragment
make -j"$(nproc)"
qemu-system-x86_64 -kernel Arch/x86/boot/bzImage \
                   -initrd rootfs.cpio.gz -S -s \
                   -append nokaslr

На другом терминале, внутри дерева ядра Linux, предположим, что вы хотите начать отладку с start_kernel:

gdb \
    -ex "add-auto-load-safe-path $(pwd)" \
    -ex "file vmlinux" \
    -ex 'set Arch i386:x86-64:intel' \
    -ex 'target remote localhost:1234' \
    -ex 'break start_kernel' \
    -ex 'continue' \
    -ex 'disconnect' \
    -ex 'set Arch i386:x86-64' \
    -ex 'target remote localhost:1234'

и мы сделали !!

Для модулей ядра см .: Как отлаживать модули ядра Linux с QEMU?

Для Ubuntu 14.04, GDB 7.7.1, была нужна hbreak, программные точки останова break игнорировались. Не так больше в 16.10. Смотрите также: https://bugs.launchpad.net/ubuntu/+source/qemu-kvm/+bug/901944

Грязный disconnect и то, что следует за ним, должны обойти ошибку:

Remote 'g' packet reply is too long: 000000000000000017d11000008ef4810120008000000000fdfb8b07000000000d352828000000004040010000000000903fe081ffffffff883fe081ffffffff00000000000e0000ffffffffffe0ffffffffffff07ffffffffffffffff9fffff17d11000008ef4810000000000800000fffffffff8ffffffffff0000ffffffff2ddbf481ffffffff4600000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000801f0000

Связанные темы:

Известные ограничения:

Смотрите также:

Ответ БьорнИДа не сработал для меня. После первого продолжения точка останова не достигается, и при прерывании я бы увидел такие строки:

0x0000000000000000 in ?? ()
(gdb) break rapl_pmu_init
Breakpoint 1 at 0xffffffff816631e7
(gdb) c
Continuing.
^CRemote 'g' packet reply is too long: 08793000000000002988d582000000002019[..]

Я предполагаю, что это как-то связано с разными режимами процессора (реальный режим в BIOS или длинный режим, когда Linux загрузился). В любом случае, решение состоит в том, чтобы сначала запустить QEMU без ожидания (то есть без -S):

qemu-system-x86_64 -enable-kvm -kernel Arch/x86/boot/bzImage -cpu SandyBridge -s

В моем случае мне нужно было что-то сломать во время загрузки, поэтому через несколько секунд я запустил команду gdb. Если у вас есть больше времени (например, вам нужно отладить модуль, загруженный вручную), тогда время не имеет значения.

gdb позволяет указать команды, которые должны запускаться при запуске. Это делает автоматизацию немного проще. Чтобы подключиться к QEMU (который уже должен быть запущен), прервать функцию и продолжить выполнение, используйте:

gdb -ex 'target remote localhost:1234' -ex 'break rapl_pmu_init' -ex c ./vmlinux
3
Lekensteyn

Когда вы пытаетесь запустить vmlinux exe, используя gdb, первое, что нужно сделать на gdb - это ввести cmds:

(gdb) целевой удаленный локальный хост: 1234

(gdb) break start_kernel

(Продолжить)

Это сломает ядро ​​в start_kernel.

2
Ritesh

На мой взгляд, лучшее решение для отладки ядра - это использовать GDB из среды Eclipse. Вы должны просто установить соответствующий порт для GDB (должен совпадать с тем, который вы указали в строке запуска qemu) в разделе удаленной отладки. Вот руководство: http://www.sw-at.com/blog/2011/02/11/linux-kernel-development-and-debugging-using-Eclipse-cdt/

1
Alex Hoppus