赞
踩
再前一章的文章中我们简单介绍了GPU-PV实现原理,但是也是在IDA 反编译器中通过静态分析大概看了一下GPU-PV大致流程,如果想更加了解GPU-PV我们必须从调试器中去动态跟踪GPU-PV的实现原理,因此一个好的调试环境就是弄懂GPU-PV的基础。本文的目的就是让大家可以方便搭建一个Windows Hyper-V + GPU-PV的调试环境,为以后调试GPU-PV做好基础
Hyper-v是windows推出的一种虚拟化技术,允许你在Windows上通过虚拟机同时运行多个操作系统。
Hyper-V 提供了专门基于硬件半虚拟化驱动, 这意味着每个虚拟机都可以运行在虚拟硬件上运行,和Vmware一样Hyper-V允许你创建虚拟磁盘驱动,虚拟机交换机和其他虚拟设备。所有这些外设都可以添加到虚拟机。
本文讨论的是基于X86的架构Hyper-V, 所以和KVM一样也存在特权分层(本文不会讲解虚拟化基本原理,而是着重介绍如何通过windbg双机调试来认识Hyper-V GPU虚拟化技术,如果读者有兴趣可以参考https://www.cnblogs.com/Chary/p/15954246.html去了x86虚拟化VMM为啥要分Root Mode , None Root mode).
Hyper-V high Level Architecture
Hyper-V中通常叫做 "Partitions"(分区),通常存在三种Partitions
1. Root partitions (根分区)
2. Guest Partition(非根分区), 其实Guest Partition又分为 enlightened guest partitions 和 unenlightened guest partitions, 本文不会对hyper-V概念逐一讲解,所以我们本文中不会过多介绍。文中统一成为Guest Partition.
简单来说在Hyper-V Root partition是一个拥有所有特权的Host OS,你可以在里面运行任意程序。 所以我们可以将根分区视为一个特殊的特权host,它与Hypervisor(虚拟化管理程序)一起工作来完成对应虚拟化工作。
Hyper-V Management Services就运行在Root partition, 我们可以通过Hyper-V Management Services来完成对虚拟机的创建。 在KVM中,Host和Guest通信是通过 VM-Entry和VM-Exit来通信,在Hyper-V中换了一个名词叫做hypercalls。也就是说Hyper-V中Host和Guest通信时通过hypercalls方式来进行的。 除此之外Hyper-V还提供一个非常重要的组件 VMBus. VMBus是一个IPC组件除了可以让Guest Partition和Host Partition通信外,还可以让Guest Partition和Guest Partition之间通信。
在对Hyper-V有一定的了解后,我们开始着重讲解如何搭建Hyper-V调试环境,搭建Hyper-V双机调试环境需要Host端的内核进行参与,因此没办法调试host的内核和Hypervisor。 因为你如果hostkernel被挂住了,你是没办法利用调试器进行单步调试的。因为我们必须利用到hyper-v的嵌套虚拟化技术(经过本人测试发现hyper-v嵌套虚拟化比KVM稳定多,还是不得不佩服微软),所以我们需要创建一个虚拟机,在虚拟机中开启Hyper-V.让这台虚拟机成为 Root Partitions. 调试环境架构图大体图下:
Level 0 = 在物理主机上运行的代码。运行虚拟机管理程序
Level 1 = Level 0 的hypervisor对应的虚拟机, 其运行的我们想要调试的Hypersor和GPU PV
Level 2 = Level 1 hypervisor对应的虚拟机
因为我们想要调试Hypervisor和GPU PV,我们要我们将作为另一个虚拟机管理程序的来guest来运行我们想要调试的hypervisor。
好了,澄清上述概念以后,我们可以开始搭建调试环境了:
https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v
2.1 开启CPU VT-x, 不然Hyper-V没办法支持嵌套虚拟化,也可以在Host机上运行如下PS脚本完成VT-X的开启
Set-VMProcessor -VMName <VMName> -ExposeVirtualizationExtensions $true
2.2 因为我们要在Guest(虚拟机)内部调试Hypervisor(虚拟机管理程序),因此我们也必须在Guest内部启用 Hyper-V(此处有记录)。之后重新启动Guest虚拟机。
2.3 在Leve1对应的host内配置调试命令
bcdedit /hypervisorsettings serial DEBUGPORT:1 BAUDRATE:115200
bcdedit /set hypervisordebug on
bcdedit /set hypervisorlaunchtype auto
bcdedit /dbgsettings serial DEBUGPORT:2 BAUDRATE:115200
bcdedit /debug on
为了与这些串行端口通信,我们需要将它们暴露给 L0 主机,这是我们使用的操作系统。在 Hyper-V 管理器中,右键单击虚拟机,单击“设置”,然后在左窗格中的“硬件”下,选择 COM1。从选项中选择一个命名管道并将其设置为“debug_hv”。对 COM2 执行相同操作,并将其名称设置为“debug_kernel”。
这将在主机上创建两个命名管道“\\.\pipe\debug_hv”和“\\.\pipe\debug_kernel”,分别用作虚拟机管理程序和根分区内核的串行调试链接。
以管理员权限启动两个的WinDbg Preview 实例,并将它们的输入设置为两个命名管道。为此,请单击:开始调试 -> 附加到内核 (ctrl+k)。
重启L1虚拟机, 这样我们就可以在我们使用操作系统通过Windbg调试hypervisor了 同样你也可以调试GPU-PV.
在L1虚拟机对应的windbg中,我们可以查看 hypercall对应指令:
GPU-PV环境搭建网上早就有很多介绍,具体可以参考github Easy-GPU-PV
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。