使用 qemu 和 gdb 调试内核,断点不起作用?
debugging kernel with qemu and gdb, breakpoint not working?
为了尝试使用 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 -nographic -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' 处停止。我不知道这有什么问题。
而且我也不知道在没有上面的磁盘映像的情况下如何启动。我怎样才能 运行 它与香草 linux 内核? (我用过它,但有上面的磁盘和磁盘映像,我试过没有它们但它没有启动)。
请帮忙。
在我发布问题后不久就解决了,我忘记回答了。
这是因为 KASLR(内核地址 space 位置随机化)。您应该在内核配置中禁用它,或者在引导参数中提供选项。 (没有它,内核映像位于随机位置,导致调试符号位置和实际代码位置不匹配)。对于 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'(或中断)。
为了尝试使用 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 -nographic -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' 处停止。我不知道这有什么问题。
而且我也不知道在没有上面的磁盘映像的情况下如何启动。我怎样才能 运行 它与香草 linux 内核? (我用过它,但有上面的磁盘和磁盘映像,我试过没有它们但它没有启动)。
请帮忙。
在我发布问题后不久就解决了,我忘记回答了。
这是因为 KASLR(内核地址 space 位置随机化)。您应该在内核配置中禁用它,或者在引导参数中提供选项。 (没有它,内核映像位于随机位置,导致调试符号位置和实际代码位置不匹配)。对于 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'(或中断)。