我正在尝试研究使用 QEMU 进行内核调试。我最初尝试过,但由于没有虚拟文件系统而失败。的答案这个帖子建议应该有一个虚拟文件系统。但它没有讨论如何创建用于内核调试的虚拟 FS 以及如何将其传递给 qemu。你能帮我吗?
答案1
根据您想要使用的发行版,有多种方法可以创建文件系统映像,例如本文带领您走过艰苦的道路《从零开始的Linux》系统。
一般来说, 你任何一个使用 创建 QEMU 映像qemu-img
,获取某些发行版的安装介质并使用QEMU使用安装介质来准备映像(本页解释了 Debian GNU/Linux 的流程)或者使用别人准备的图像。
QEMU Wikibook 的这一部分包含您需要的所有信息。
编辑:
正如吉尔斯对链接问题的回答所暗示的那样,您不需要完整的根文件系统来进行测试,您可以使用initrd
图像(例如,Arch Linux 的 initrd,如下所示)
答案2
QEMU + GDB 分步过程在 Ubuntu 16.10 主机上测试
为了快速从头开始,我在以下位置制作了一个最小的全自动 QEMU + Buildroot 示例:https://github.com/cirosantilli/linux-kernel-module-cheat主要步骤如下。
首先获取根文件系统rootfs.cpio.gz
。如果您需要一个,请考虑:
- 一个最小的
init
可执行映像:定制 Linux 发行版仅运行一个程序,仅运行一个程序 | Unix 和 Linux 堆栈交换 - Busybox交互系统:最小的 Linux 实现是什么? | Unix 和 Linux 堆栈交换
然后在Linux内核上:
git checkout v4.9
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
在另一个终端上,假设您想从以下位置开始调试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'
我们完成了!
对于内核模块,请参阅:如何使用 QEMU 调试 Linux 内核模块? |堆栈溢出
hbreak
对于 Ubuntu 14.04,需要GDB 7.7.1 ,break
软件断点被忽略。 16.10 中情况不再如此。也可以看看:https://bugs.launchpad.net/ubuntu/+source/qemu-kvm/+bug/901944
混乱disconnect
以及随后发生的事情是为了解决错误:
Remote 'g' packet reply is too long: 000000000000000017d11000008ef4810120008000000000fdfb8b07000000000d352828000000004040010000000000903fe081ffffffff883fe081ffffffff00000000000e0000ffffffffffe0ffffffffffff07ffffffffffffffff9fffff17d11000008ef4810000000000800000fffffffff8ffffffffff0000ffffffff2ddbf481ffffffff4600000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000801f0000
相关主题:
- https://sourceware.org/bugzilla/show_bug.cgi?id=13984可能是 GDB 错误
- gdb - 远程“g”数据包回复太长 |堆栈溢出
- http://wiki.osdev.org/QEMU_and_GDB_in_long_modeosdev.org 像往常一样是解决这些问题的绝佳来源
- https://lists.nongnu.org/archive/html/qemu-discuss/2014-10/msg00069.html
也可以看看:
- https://github.com/torvalds/linux/blob/v4.9/Documentation/dev-tools/gdb-kernel-debugging.rst官方 Linux 内核“文档”
- 如何使用GDB和QEMU调试Linux内核? |堆栈溢出
已知限制:
- Linux 内核不支持(甚至在没有补丁的情况下无法编译)
-O0
:如何对Linux内核进行反优化并使用-O0进行编译? |堆栈溢出 - 即使在修复之后,GDB 7.11 也会在某些类型的制表符补全方面让您大吃一惊
max-completions
:大型二进制文件的制表符补全中断 |堆栈溢出可能是该补丁中未涵盖的一些极端情况。因此,ulimit -Sv 500000
在调试之前执行此操作是明智的做法。当我file<tab>
为以下参数完成filename
选项卡时,特别爆炸:sys_execve
Linux 内核中的 sys_execve() 系统调用可以同时接收绝对路径或相对路径吗? |堆栈溢出