Debugging a Generation 2 Virtual Machine

Hyper-V is based on the 440BX (PCI) chipset for emulation. The decision to use this chipset started years ago with Connectix Virtual PC.  The advantage of using an emulated chipset based on a popular motherboard like the 440BX, along with associated peripherals, is the compatibility with a large number of operating systems.

 

Windows Server 2012 R2 introduced the Generation 2 Virtual Machine. It is a UEFI based design, removing emulated devices and replacing them with synthetic devices. Generation 2 VMs no longer support the following devices:

  • Legacy BIOS
  • COM Ports
  • Floppy Controller
  • DMA Controller
  • i8042 keyboard controller
  • PS/2 devices
  • Legacy NIC
  • IDE Controller
  • S3 video
  • PCI BUS
  • Programmable Interrupt Controller
  • Programmable Interrupt Timer
  • Super I/O Device

 

After reading this list you might ask the question – how do I debug a Generation 2 VM?

 

The COM port is not actually removed from a Generation 2 VM. The port is turned off by default and not present in the user interface. To enable it for debugging use the following steps.

 

1.  Shutdown the VM.  You can verify the VM is off using the below PowerShell command.

 

2.  Turn off secure boot using the following PowerShell Command.

set-vmfirmware

image002

 

3.  Set a COM port path using the following PowerShell command where the path is equal the named pipe.

set-vmcomport

image003

 

4.  To confirm the COM port settings after making the change, use the following command.

get-vmcomport

image004

 

5.  Restart the Virtual Machine using the following command.

Start-VM –Name VM2

image005

 

6.  Inside the guest VM, you can confirm that UEFI has been disabled with the following command. The results are False if UEFI was successfully disabled in step 2 above.

Confirm-SecureBootUEFI

image006

 

7.  Enable Kernel Debugging using BCDEdit.

BCDEdit /debug ON

image007

image008

 

8.  Configure the debugger to connect to the pipe:

KernelDebug1

 

9.  Connect the debugger and break in with Ctrl+Break:

KernelDebug2