上一篇介绍了“GDK7+NanoCode调试学习系列6–Intel System Studio(ISS)搭建环境调试GDK7”,本篇继续学习,将尝试使用NanoCode来分析Linux虚机KVM模块的相关调用。
本调试目标机Linux内核版本为5.3.0-62-generic。
准备工作:
关于kvm.ko符号和内核源码的下载,请参考以前的文章(https://blog.csdn.net/henly1217/article/details/107662054);
kvm.ko处于/usr/lib/debug/lib/modules/5.3.0-62-generic/kernel/arch/x86/kvm目录,和其他drivers不太一样。
复制带符号的kvm.ko到主机,放入以前的符号目录。
使用kvm驱动模块的功能,需要安装应用层工具qemu,应用层通过/dev/kvm文件符号和驱动通信。
sudo su - // 进入root
mount -t debugfs debugfs /opt/debugfs // mount debugfs 到/opt/debufs下
cd /opt/debugfs
ls kvm
可以看到kvm的debugfs, 其中2448-12目录正是当前运行的这个虚拟机的debugfs.
开始调试:
- 参考系列3中断并设置符号和内核源码路径。
- 已经成功加载了内核符号了,通过(.srcpath+ 内核源码路径)来设置一下源码路径,通过(x kvm!*)来加载一下kvm的符号。
环境已经准备就绪了。
我们尝试使用NanoCode提供的Views->JTAG events的VMLaunch和VMExit来设置一下,看看是否能够中断?
先设置VMLaunch,然后g起来
有点遗憾,启动VMLuanch是自动断下来了,可以获取不到执行信息,启动VMExist没有断下来
我们暂时跳过JTAG events,继续研究一下源代码。
在virt/kvm/kvm_main.c里面有kvm_vcpu_init和kvm_vcpu_uninit函数,我们先对他们下个断点。
bp kvm!kvm_vcpu_init
bp kvm!kvm_vcpu_uninit
然后重新g起来;
然后启动另一个虚拟机,果然,kvm_vcpu_init断点命中,这是虚拟机启动的初始化函数,我们稍微调试一下,
kv //看下调用堆栈
dv //查看临时变量,但是没有显示出来??
p // 先单步一次
dv //在查看临时变量,出来了,当前的vcpu=0xffff8a8f`66f50000
然后重新g起来,我们关闭刚刚启动的虚拟机,看看kvm_vcpu_uninit是否断下?没有问题,也断下了,而且参数vcpu=0xffff8a8f`66f50000。
- 简单分析启动和关闭之后,我们在研究一下应用层和驱动是通过哪里交互的,应用层和驱动通过/dev/kvm来交互,通过kvm_dev_ioctl来实现,如下图,然后根据ioctl来分发不同的请求,包括创建新的虚拟机kvm_dev_ioctl_create_vm,kvm_arch_dev_ioctl会根据不同的架构,调用到不同架构的实现里面去。
我们尝试对kvm_dev_ioctl下断点(bp kvm!kvm_dev_ioctl),很快命中断点,ioctl=0xae03,刚好是KVM_CHECK_EXTENSION
- 至此,我们简单地配合源码和调试器,分析了kvm的几个函数。
总结:
在调试器下简单分析kvm的创建,启动/关闭,和通信的加个函数
待续。。。
————————————————版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/henly1217/article/details/108491230
最后编辑:沈根成 更新时间:2024-12-09 10:54