linux - 使用 qemu 和 gdb 调试内核,断点不起作用?

标签 linux linux-kernel arm gdb linux-device-driver

为了尝试使用 qemu 和 gdb 调试 aarch64 的内核(该多好啊),我尝试了这个。

  • 使用 CONFIG_DEBUG_INFO 构建内核

  • 使用“configure --target-list=aarch64-softmmu --enable-debug”和“make”和“make install”构建 qemu。

  • 然后我就跑了,
    qemu-system-aarch64 -machine virt -cpu cortex-a57 -machine type=virt -ngraphic -smp 1 -m 2048 -kernel arch/arm64/boot/Image -append "earlyprintk console=ttyAMA0 rootwait root=/dev/vda2"-drive if=none,file=/home/ckim/N1SDP/arm-reference-platforms/output/n1sdp/grub-ubuntu.img,id=disk1 -device virtio-blk-device,drive=disk1 -s -S

  • 并在另一个 shell 中运行,“gdb-multiarch vmlinux -x gdbcmd”。 gdbcmd 包含

    设置架构aarch64 设置串口波特率115200 目标远程:1234

如果没有 -S 选项,qemu 将继续进行 Linux 引导。 (它开始于

[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x411fd070]
[    0.000000] Linux version 5.4.21 (ckim@chan-ubuntu) (gcc version 9.2.1 20191025 (GNU Toolchain for the A-profile Architecture 9.2-2019.12 (arm-9.10))) #6 SMP PREEMPT Fri Jan 22 11:43:52 JST 2021
[    0.000000] Machine model: linux,dummy-virt
[    0.000000] efi: Getting EFI parameters from FDT:
[    0.000000] efi: UEFI not found.
....

但使用 -S 时,它会停止并等待调试器发出继续命令。
在调试器中,我可以设置像 b start_kernel 这样的断点,它会做出响应。但是如果我输入“cont”,qemu 就会开始启动,而不会在“start_kernel”处停止。我不知道这有什么问题。
而且我也不知道如何在不提供上面的磁盘镜像的情况下启动。我如何使用 vanilla linux 内核运行它? (我使用了它,但使用了上面的磁盘和磁盘镜像,我在没有它们的情况下尝试了它,但它无法启动)。

请帮忙。

最佳答案

在我发布问题后不久就解决了这个问题,但我忘了给出答案。

这是因为 KASLR(内核地址空间位置随机化)。您应该在内核配置中禁用它,或者在启动参数中提供选项。 (如果没有它,内核镜像位于随机位置,导致调试符号位置和实际代码位置之间不匹配)。对于 aarch64,此 KASLR 默认开启。
就我而言,我是这样做的:

${QEMU_DIR}/qemu-system-aarch64 -M ${QMACHINE} -cpu cortex-a72 -kernel ${LINUX_DIR}/arch/arm64/boot/Image -initrd ${BUSYBOX_DIR}/initramfs.cpio.gz --append "root=/dev/ram init=/init nokaslr" -m 2048M -nographic

我必须使用“hb”(或 hbreak(硬件中断))而不是“b”(或中断)。

关于linux - 使用 qemu 和 gdb 调试内核,断点不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65844209/

相关文章:

linux - 将 MS 文档转换为 csv 文件

linux - USB 设备枚举失败 : "device descriptor read/64, error -32"

debugging - 通过 Cortex-M3 CPU 上的 printf 进行输出调试,在 BKPT 指令处停顿 + 关于 JTAG 和 sw 端口的混淆

linux - linux x86平台学习ARM所需工具

linux - 为 arm 交叉编译 glibc

linux - 在Linux中使用.sh文件将csv文件数据传递到命令中

linux - 使用套接字绕过内核

c - 在没有 LD_PRELOAD 的情况下在用户级别拦截系统调用

exception - Linux中除以零异常处理

c - copy_from_user()的实现