I have a Windows 7 machine at home that's been in use for about 15 years. Due to hardware degradation in recent years, it can no longer boot normally, but I didn't want to purchase additional hardware. In late August last year, I started experimenting with KVM virtualization on my Arch Linux system. During that time, I had a sudden idea: could I run this system in a virtual machine? Thus began this practical experiment:
I connected the Win 7 machine's hard drive to my Arch Linux system using a SATA-to-USB adapter, which was mounted as /dev/sdc. Then I used qemu-img to convert it to a qcow2 file:
sudo qemu-img convert -f raw -O qcow2 /dev/sdc ./neo_win7.qcow2
Next, I used virt-manager to create a new virtual machine with default parameters and attempted to boot from neo_win7.qcow2. As expected, it blue-screened with error 0x7B:
After consulting relevant tutorials, I initially determined that the issue might be registry-related. So I added a Windows 7 installation ISO to the virtual machine and configured the boot options to only boot from the ISO.
It booted successfully. In the installation interface, I selected Language, Time, and Keyboard → clicked "Next". At the bottom left, "Repair your computer" appeared → I clicked to enter. The system searched for installed Windows installations. Even if it doesn't find any, that's fine—we just need the command prompt to access the registry.
In the "System Recovery Options" window, I selected "Command Prompt". In the command prompt, I typed:
diskpart
list volume
I located and noted the Windows system volume corresponding to neo_win7.qcow2.
In the command prompt, I typed regedit to open the Registry Editor. A window appeared where I selected HKEY_LOCAL_MACHINE, then clicked the File menu in the upper left → Load Hive.
I navigated to the system volume of neo_win7.qcow2, following this path: Drive:\Windows\System32\Config\SYSTEM. I gave it a name, such as temp.
After loading, in the Registry Editor's main interface, I saw temp appear under HKEY_LOCAL_MACHINE.
Following the instructions from these links:
P2V - Windows Physical to Linux KVM - Blue Screen
STOP 0x0000007B Resolved on P2V’d Windows SBS 2011
I modified the registry accordingly. Either reference works. After completing the registry modifications, I selected temp → File -> Unload Hive.
However, after completing these steps, the blue screen issue persisted.
At this point, I suspected the blue screen was caused by missing VirtIO drivers in the neo_win7.qcow2 system. Similar to the registry modification steps, I booted the system using the Win7 installation disc (SATA, CDROM) while also mounting Red Hat's virtio-win-0.1.173.iso (SATA, CDROM).
My plan was to boot from the installation disc, then use a command like: dism /Image:SystemDrive:\ /Add-Driver /Driver:VirtIODrive:\viostor\w7\amd64 /Recurse to inject the VirtIO drivers into the neo_win7.qcow2 system, thereby fixing the blue screen (if VirtIO drivers were indeed the cause).
But at this point, I noticed a critical issue: the neo_win7.qcow2 system was Windows 7 Ultimate 32-bit Chinese Edition! This meant that if I used a 64-bit Win7 installation disc to inject drivers into a 32-bit Win7 system, the following error would occur:
"An error occurred. Unable to service a x86-based image from a x64-based host that does not support WOW64. Retry the operation from a host environment that supports WOW64."
Since the 64-bit installation disc wouldn't work, I switched to a 32-bit Win7 installation disc, attempting to inject drivers into the 32-bit neo_win7.qcow2 system. However, I encountered another difficulty: when entering the boot interface, clicking anywhere would cause the mouse cursor to lock up, requiring Ctrl+Alt to unlock (essentially stuck at step one), making it impossible to click any interface elements.
Fortunately, I already had a 64-bit Win7 virtual machine installed on my Linux system. Since 64-bit Win7 includes the WOW64 compatibility layer, I could bypass dism and use C:\Windows\SysWoW64\Dism.exe to inject drivers into the 32-bit neo_win7.qcow2 system.
So I attached neo_win7.qcow2 (VirtIO) and virtio-win-0.1.173.iso (SATA, CDROM) to the existing 64-bit Win7 virtual machine.
Initially, the 64-bit Win7 VM only recognized the virtio-win-0.1.173.iso (SATA) as a drive but couldn't recognize neo_win7.qcow2 because it was using the VirtIO bus, and the 64-bit Win7 VM hadn't had VirtIO drivers injected yet. To recognize it, I first needed the 64-bit Win7 to inject VirtIO drivers into itself!
"Injecting drivers into itself": In the installation disc's command prompt, you'd use the drvload command to inject drivers. But in the existing 64-bit Win7 VM, instead of drvload, use pnputil:
pnputil -i -a VirtIODrive:\viostor\w7\amd64\viostor.inf
↑ Note: Since the existing 64-bit Win7 VM is 64-bit architecture, the directory under \viostor\w7 is amd64, not x86.
Right after running this command, the system with freshly injected VirtIO drivers instantly recognized the neo_win7.qcow2 with VirtIO bus type, and a notification appeared for the corresponding disk:
Next, I used the 64-bit Win7 VM to inject drivers into the neo_win7.qcow2 system.
In this example, neo_win7.qcow2 corresponded to three drive letters: E, F, G, where F was the system drive. The VM was 64-bit, neo_win7.qcow2 was 32-bit. For a 64-bit system to inject drivers into a 32-bit system, it relies on the WOW64 compatibility layer:
C:\Windows\SysWOW64\Dism.exe /Image:F:\ /Add-Driver /Driver:D:\viostor\w7\X86 /Recurse
↑ Note: Since neo_win7.qcow2 is 32-bit, use \viostor\w7\X86, not \viostor\w7\amd64.
At this point, I successfully injected VirtIO drivers into neo_win7.qcow2. However, after setting the boot option to neo_win7.qcow2 in virt-manager, it still blue-screened, and the cause remained unclear.
Since the Win 7 32-bit system was from an earlier era, I began to wonder if the issue was caused by the virtual CPU architecture being too modern. This time, I selected pc-i440fx for the Chipset and Penryn for the CPU Model to approximate the Win7 release era, attached neo_win7.qcow2 (SATA), and booted.
This time, for the first time, the boot animation loaded successfully (light dots merging into the Microsoft logo) before blue-screening, instead of black screen followed by blue screen! This indicated that the system boot kernel had loaded but couldn't access the boot device.
If it were CPU incompatibility / HAL error / core system file corruption → it would typically blue screen before the logo. Since the logo appeared → CPU/kernel/HAL are fine, the problem is concentrated in the storage driver stage.
Next, I changed the neo_win7.qcow2 bus type from SATA to VirtIO, and it finally booted successfully:
So now it appears the conditions for successful boot are: