Вопрос по gdb, linux, linux-kernel, qemu – Как отладить ядро Linux с помощью GDB и QEMU?
========================================================================================

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

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

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

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

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

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

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

жения точка останова не достигается, и при прерывании я бы увидел такие строки:

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

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

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



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

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

Лучше всего было бы взглянуть на достойный учебник по GDB, чтобы понять, что вы делаете.[Вот этот](https://web.archive.org/web/20180401080715/www.dirac.org/linux/gdb/) выглядит довольно мило.



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

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

(gdb) break start\_kernel

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

Это сломает ядро в start\_kernel.



**Step-by-step procedure tested on Ubuntu 16.10 host**

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

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

a minimal `init`-only executable image: <https://unix.stackexchange.com/questions/122717/custom-linux-distro-that-runs-just-one-program-nothing-else/238579#238579>
a Busybox interactive system: <https://unix.stackexchange.com/questions/2692/what-is-the-smallest-possible-linux-implementation/203902#203902>
Тогда на ядре Linux:

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

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

Для модулей ядра смотрите:[Как отлаживать модули ядра Linux с QEMU?](https://stackoverflow.com/questions/28607538/how-to-debug-linux-kernel-modules-with-qemu/44095831#44095831)

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

Грязный`disconnect` и что после этого нужно обойти ошибку:

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

<https://sourceware.org/bugzilla/show_bug.cgi?id=13984> might be a GDB bug
[Remote 'g' packet reply is too long](https://stackoverflow.com/questions/8662468/remote-g-packet-reply-is-too-long)
<http://wiki.osdev.org/QEMU_and_GDB_in_long_mode> osdev.org is as usual an awesome source for these problems
<https://lists.nongnu.org/archive/html/qemu-discuss/2014-10/msg00069.html>
`nokaslr`: <https://unix.stackexchange.com/questions/397939/turning-off-kaslr-to-debug-linux-kernel-using-qemu-and-gdb/421287#421287>
Известные ограничения:

the Linux kernel does not support (and does not even compile without patches) with `-O0`: [How to de-optimize the Linux kernel to and compile it with -O0?](https://stackoverflow.com/questions/29151235/how-to-de-optimize-the-linux-kernel)
GDB 7.11 will blow your memory on some types of tab completion, even after the `max-completions` fix: [Tab completion interrupt for large binaries](https://stackoverflow.com/questions/597777/tab-completion-interrupt-for-large-binaries) Likely some corner case which was not covered in that patch. So an `ulimit -Sv 500000` is a wise action before debugging. Blew up specifically when I tab completed `file<tab>` for the `filename` argument of `sys_execve` as in: <https://stackoverflow.com/a/42290593/895245>
Смотрите также:

<https://github.com/torvalds/linux/blob/v4.9/Documentation/dev-tools/gdb-kernel-debugging.rst> official Linux kernel "documentation"
[Linux kernel live debugging, how it's done and what tools are used?](https://stackoverflow.com/questions/4943857/linux-kernel-live-debugging-how-its-done-and-what-tools-are-used)



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