kvm因为是和qemu一起跑的,想必网上搜出来的都是用QEMU-gdb去调试kernel, 本文记录的则是利用kgdb调试kvm module, 利用gdb调试qemu-kvm, 这样就能够在串口调试的基础上更方便的追踪程序的执行流了。
Configuration
我用的是Hikey960的板子,里面有4个Cortex-A73和4个Cortex-A53的核,ARMv8, aarch64的架构。QEMU用的4.10.2
Run qemu-KVM
需要注意的是目前Cortex-A73还没有被支持,所以直接跑的话如果vcpu被调度到A73的核上那么是会崩的, qemu会报不支持的cpu类型,所以我们要用taskset
来指定线程被调度的核(0-3是A53, 4-7是A73)
1 | taskset -c 0-3 qemu-system-aarch64 -m 1024 -M virt -cpu cortex-a53 -smp 4 -bios "bios.fd" -nographic -device -virtio-blk-device,drive-image -drive if=none,id=image,file="disk.img" -enable-kvm |
Debug QEMU-kvm
首先我们要下载qemu的源码并编译,之后只要正常用gdb调试程序一样即可,不过依旧要注意的是使用taskset
来绑定核:
1 | taskset -c 0 gdb --args qemu-system-aarch64 -m 1024 -M virt -cpu cortex-a53 -smp 4 -bios "bios.fd" -nographic -device -virtio-blk-device,drive-image -drive if=none,id=image,file="disk.img" -enable-kvm |
这样启动后只要使用run
就可以执行qemu-kvm了。
Remote kgdb kvm module
与调试Xen遇到的情况一样,由于kvm是Hypervisor,所以不能放到qemu里面去调试,但是与Xen不同的是kvm属于Linux的一个module, 这样我们就可以借助kgdb来调试kvm module部分的代码:
参考了: Reference
- target ARM Board (e.g. Hikey960)
- Host LinuxPC (e.g. Ubuntu) target is connected to host via Serial (e.g. ttyAMA6 of target <—> ttyUSB0 of host)
在这之前请先保证Host可以通过串口连接target~
Enable feature in kernel config:
1 | CONFIG_KGDB = y |
Recompile kernel and reboot target Reinstall kernel modules
- Target
1 | # you can add linux_cmdline arg: kgdbwait kgdboc=ttyAMA6,115200 |
我的板子用kgdbwait并没有什么效果..所以最后还是用了sysrq-trigger
的方法来暂停kernel
- Host
1 | apt-get install gdb-multiarch |
Remote Cross-debugging pogram
You need to ensure target can connect to host via Network
- Target
1 | gdbserver :port ./program args |
- Host
1 | gdb-multiarch ./program (cross-compiled) |
之后只要在Host上使用对应的gdb命令就可以调试运行在target上的Kernel(kvm module)了.
めでたしめでたし~