如何使用 QEMU 和 KGDB 调试 Linux 内核? [英] How to debug the Linux kernel with QEMU and KGDB?
问题描述
我已经能够使用以下方式启动基于 powerpc 的系统(具体来说是 MPC8544DS)来调用 qemu (v1.7.0)
qemu-system-ppc -M mpc8544ds -m 512 -kernel zImage -s -nographic -initrd busyboxfs.img -append "root=/dev/ram rdinit=/bin/sh kgdboc=ttyS0,115200 kgdbwait"
其中 zImage 是自定义交叉编译的 Linux 内核 (v2.6.32),它启用并编译了 KGDB(用于启动代码调试),busyboxfs.img
是基于 busybox 的 rootfs.
由于我对 Qemu 使用了 -s
标志,所以我可以像这样使用跨 gdb 闯入内核:
(gdb) 目标远程 localhost:1234使用 localhost:1234 进行远程调试mem_serial_in(p=<值优化输出>,偏移=5)在drivers/serial/8250.c:405第405话
但是,如果我删除 -s
标志并尝试通过 /dev/ttyS0
进入内核,它会给我一个权限被拒绝的错误:
(gdb) 设置远程波特率 115200(gdb) 目标远程/dev/ttyS0没有权限
是不是因为已经被Qemu控制了?此外,在 Internet 上的示例中,kgdboc 已设置为 ttyAMA0
,我开始理解它代表 AMBA
总线,它特定于基于 ARM 的系统.PowerPC 有类似的东西吗?我在这里做错了吗?
KGDB + QEMU 一步一步
首先,QEMU 的 -gdb
选项严格来说比 KGDB 更强大,因此您可能想改用它:如何使用 GDB 和 QEMU 调试 Linux 内核? 然而,QEMU 是一种使用 KGDB 的简单方法为真正的硬件做准备.我在以下位置发布了一些 Raspberry Pi KGDB 指针:Linux内核实时调试,是怎么做的,用的什么工具?
如果您想从头开始快速入门,我在以下位置制作了一个最小的全自动 Buildroot 示例:https://github.com/cirosantilli/linux-kernel-module-cheat/tree/d424380fe62351358d21477658d2147758d21409dbc5
主要步骤是:
编译内核:
CONFIG_DEBUG_KERNEL=yCONFIG_DEBUG_INFO=yCONFIG_CONSOLE_POLL=yCONFIG_KDB_CONTINUE_CATASTROPHIC=0CONFIG_KDB_DEFAULT_ENABLE=0x1CONFIG_KDB_KEYBOARD=yCONFIG_KGDB=yCONFIG_KGDB_KDB=yCONFIG_KGDB_LOW_LEVEL_TRAP=yCONFIG_KGDB_SERIAL_CONSOLE=yCONFIG_KGDB_TESTS=yCONFIG_KGDB_TESTS_ON_BOOT=nCONFIG_MAGIC_SYSRQ=yCONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1CONFIG_SERIAL_KGDB_NMI=n
其中大部分不是强制性的,但这是我测试过的.
添加到您的 QEMU 命令:
-append 'kgdbwait kgdboc=ttyS0,115200' -串行 tcp::1234,服务器,nowait
使用以下命令从 Linux 内核源代码树的根运行 GDB:
gdb -ex 'file vmlinux' -ex 'target remote localhost:1234'
在 GDB 中:
(gdb) c
启动应该完成.
在 QEMU 中:
echo g >/proc/sysrq-触发器
GDB 应该会崩溃.
现在我们完成了,您可以照常使用 GDB:
b sys_writeC
在 Ubuntu 14.04 中测试.
ARM
无法正常工作.可能与:如何在ARM上使用kgdb?
有关I have been able to boot a powerpc based system (MPC8544DS to be specific) using the following way to invoke qemu (v1.7.0)
qemu-system-ppc -M mpc8544ds -m 512 -kernel zImage -s -nographic -initrd busyboxfs.img -append "root=/dev/ram rdinit=/bin/sh kgdboc=ttyS0,115200 kgdbwait"
where zImage is a custom cross compiled Linux Kernel (v2.6.32) which has KGDB enabled and compiled in (for startupcode debugging) and busyboxfs.img
is the busybox based rootfs.
Since I'm using the -s
flag to Qemu, I can break-in to the kernel using cross gdb like so:
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
mem_serial_in (p=<value optimized out>, offset=5) at drivers/serial/8250.c:405
405 }
However if I remove the -s
flag and try to break in to the kernel over /dev/ttyS0
it gives me a permission denied error:
(gdb) set remotebaud 115200
(gdb) target remote /dev/ttyS0
permission denied
Is it because it has been held over by Qemu? Additionally in example across the internet, kgdboc has been set to ttyAMA0
which I've come to understand stands for the AMBA
bus which is specific to ARM based systems. Do we have something similar for PowerPC? Am I doing something wrong here?
KGDB + QEMU step-by-step
First, QEMU's -gdb
option is strictly more powerful than KGDB, so you might want to use that instead: How to debug the Linux kernel with GDB and QEMU? QEMU is however an easy way to play around with KGDB in preparation for real hardware. I have posted some Raspberry Pi KGDB pointers at: Linux kernel live debugging, how it's done and what tools are used?
If you want to get started quickly from scratch, I've made a minimal fully automated Buildroot example at: https://github.com/cirosantilli/linux-kernel-module-cheat/tree/d424380fe62351358d21406280bc7588d795209c#kgdb
The main steps are:
Compile the kernel with:
CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_INFO=y CONFIG_CONSOLE_POLL=y CONFIG_KDB_CONTINUE_CATASTROPHIC=0 CONFIG_KDB_DEFAULT_ENABLE=0x1 CONFIG_KDB_KEYBOARD=y CONFIG_KGDB=y CONFIG_KGDB_KDB=y CONFIG_KGDB_LOW_LEVEL_TRAP=y CONFIG_KGDB_SERIAL_CONSOLE=y CONFIG_KGDB_TESTS=y CONFIG_KGDB_TESTS_ON_BOOT=n CONFIG_MAGIC_SYSRQ=y CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 CONFIG_SERIAL_KGDB_NMI=n
Most of those are not mandatory, but this is what I've tested.
Add to your QEMU command:
-append 'kgdbwait kgdboc=ttyS0,115200' -serial tcp::1234,server,nowait
Run GDB with from the root of the Linux kernel source tree with:
gdb -ex 'file vmlinux' -ex 'target remote localhost:1234'
In GDB:
(gdb) c
and the boot should finish.
In QEMU:
echo g > /proc/sysrq-trigger
And GDB should break.
Now we are done, you can use GDB as usual:
b sys_write c
Tested in Ubuntu 14.04.
ARM
Can't get it work. Possibly related to: How to use kgdb on ARM??
这篇关于如何使用 QEMU 和 KGDB 调试 Linux 内核?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!