Previously we looked at how to install a service in a Windows VM. You can use that technique or the RunOnce tip to install some device drivers too.
But what if Windows needs the device driver in order to boot? This is the problem we faced with converting old Xen and VMWare guests to use KVM. You can’t install viostor (the virtio disk driver) which KVM needs either on the source Xen/VMWare hypervisors (because those don’t use the virtio standard) or on the destination KVM hypervisor (because Windows needs to be able to see the disk first in order to be able to boot).
Nevertheless we can modify the Windows VM off line using libguestfs to install the virtio device driver and allow it to boot.
(Note: virt-v2v will do this for you. This article is for those interested in how it works).
There are three different aspects to installing a device driver in Windows. Two of these are Windows Registry changes, and one is to install the .SYS file (the device driver itself).
So first we make the two Registry changes. Device drivers are a bit like services under Windows, so the first change looks like installing a service in a Windows guest. The second Registry change adds viostor to the “critical device database”, a map of PCI addresses to device drivers used by Windows at boot time:
# virt-win-reg --merge Windows7x64 ; ; Add the viostor service ; [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\viostor] "Group"="SCSI miniport" "ImagePath"=hex(2):73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,64,\ 00,72,00,69,00,76,00,65,00,72,00,73,00,5c,00,76,00,69,00,6f,00,73,00,74,00,6f,\ 00,72,00,2e,00,73,00,79,00,73,00,00,00 "ErrorControl"=dword:00000001 "Start"=dword:00000000 "Type"=dword:00000001 "Tag"=dword:00000040 [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\viostor\Parameters] "BusType"=dword:00000001 [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\viostor\Parameters\MaxTransferSize] "ParamDesc"="Maximum Transfer Size" "type"="enum" "default"="0" [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\viostor\Parameters\MaxTransferSize\enum] "0"="64 KB" "1"="128 KB" "2"="256 KB" [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\viostor\Parameters\PnpInterface] "5"=dword:00000001 [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\viostor\Enum] "0"="PCI\\VEN_1AF4&DEV_1001&SUBSYS_00021AF4&REV_00\\3&13c0b0c5&2&20" "Count"=dword:00000001 "NextInstance"=dword:00000001 ; ; Add viostor to the critical device database ; [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\CriticalDeviceDatabase\PCI#VEN_1AF4&DEV_1001&SUBSYS_00000000] "ClassGUID"="{4D36E97B-E325-11CE-BFC1-08002BE10318}" "Service"="viostor" [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\CriticalDeviceDatabase\PCI#VEN_1AF4&DEV_1001&SUBSYS_00020000] "ClassGUID"="{4D36E97B-E325-11CE-BFC1-08002BE10318}" "Service"="viostor" [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\CriticalDeviceDatabase\PCI#VEN_1AF4&DEV_1001&SUBSYS_00021AF4] "ClassGUID"="{4D36E97B-E325-11CE-BFC1-08002BE10318}" "Service"="viostor"
Comparatively speaking, the second step of uploading viostor.sys to the right place in the image is simple:
# guestfish -i Windows7x64 ><fs> upload viostor.sys /Windows/System32/drivers/viostor.sys
After that, the Windows guest can be booted on KVM using virtio. In virt-v2v we then reinstall the viostor driver (along with other drivers like the virtio network driver) so that we can be sure they are all installed correctly.
What about the .INF and the .CAT? Especially the .CAT is important, as Windows has to verify the driver is WHQL-signed.
Yeah, we install those “for real” later, once the VM has booted. Installing the above has been enough in our experiments to get the VM to boot on virtio and run some sort of first-boot script.
What Windows versions have you tested this on?
Paolo: W2K3, W2K8 and Windows 7.
Edit: Apparently the bootloader doesn’t care about signatures, or whatever but it does work.
Yeah, the boot loader cares about the embedded signatures but not about the catalog.
Here is another solution that might work.
Using devcon tool that is part of the DDK (WDK) the driver can be installed without HW device present in what is called by MS “Software first driver installation scenario”.
In order to do it you should execute:
“Devcon install ”
For example:
C:\WINDDK\7600.16385.0\tools\devcon\i386>devcon install C:\dev\internal-kvm-gues t-drivers-windows\viostor\Install\WXp\x86\viostor.inf
“PCI\VEN_1AF4&DEV_1001&SUB
SYS_00000000”
* Location of devcon.exe in Win7 DDK – \tools\devcon\\devcon.exe
Thanks for sharing
Here’s what i did to manually convert a PV Windows 2008 R2
domain controller, with an FC attachment to its system-volume
LUN on our SAN, to a QEMU-KVM, using the Recovery Environ-
ment installed on that LUN. I obviously disclaim any fitness-for-
any-purpose-ness of the below and would advise you not to
waste your time referring to it except as an indication of what
OCD might lead you to plodding through. I’ll also disclaim any
knowledge of this being consistent/inconsistent with anybody’s
licensing terms and/or “activation” schemes and am not saying
that i actually did the below and that it’s run for any definite
length of time but is complaining about being “unable to activate”
(which i’d reckon was just a matter of me getting the network
configured, once i cut over, so it could talk to our licensing
servers, but maybe not)
1. Cloned the LUN, exported the clone to the KVM hypervisor.
made that raw LUN the virtio boot disk for the new KVM
2. Installed the virtio-win RPM (from RHEL 5) and made the
virtio-win.vfd file in there as the read-only floppy image for
the new KVM. (If the below seems to be suspiciously free
of references to driver signing or such stuff, you can probably
trace it back to this step)
3. Boot the new KVM (with vnc graphics)
4. It blue-screens
5. It reboots into the Recovery Environment
6. Select Load Drivers and find the floppy image and the
appropriate viostor driver (amd64\win2008) and Add/Load/
Install or whatever it prompts you
7. Tell it to try to auto-repair the installation it should then have
found. It’ll fail
8. Get to the command prompt (maybe via an “Advanced”
selection at some juncture)
9. This should drop you into a windows subdirectory of the
Recovery Environment RAMdisk. In my case, that’s letter X:
10. If hunting around you can’t find it, you can
diskpart
list volumes
exit
but, one way or another, find your Windows installation (C:
here)
11. copy x:\windows\system32\drivers\viostor.sys c:\windows\system32\drivers\*.*
12. regedit
a. F3 and find
viostor
in all keys/values/data
b. This should land you in
hkey_local_machine\system\currentcontrolset\control\critcialdevicedatabase\pci…
export that key to x:\cddb.reg or something
c. Hit F3 until you land in
hkey_local_machine\system\currentcontrolset\services\viostor
and export that key to x:\viostor.reg or something
d. Navigate to hkey_users, and then File->Load Hive
c:\windows\system32\config\system
(or wherever your target system registry hive is) and mount
it on, say,
victim
e. Go to
hkey_users\victim\select
or whatever the key is that has the Current value. that’s
the Current ControlSet index
f. notepad x:\cddb.reg
g. Find…
hkey_local_machine\system\currentcontrolset
and replace globally with
hkey_users\victim\controlset001
or whatever controlset00 is actually the current
one. (You need to make sure you get the right number of
leading 0’s to hit the key, but the letter case [upper or lower]
is irrelevant, in case you care)
h. Save that and open your x:\viostor.reg and Find and
Replace as before
i. Back in regedit, Import both those .reg files
j. Go back to your victim key and File->Unload Hive it
13. Hit the Reboot button back on the Recovery menu wizard
thingy
14. Cross your fingers and it’ll maybe boot up correctly
15. If you set up a viostor NIC, you can use the still-mounted
virtual floppy to install the driver for that
Windows 8/2012 don’t use CDDB key in registry, hence registry update described here won’t work. Based on the article, http://social.msdn.microsoft.com/Forums/en-US/wdk/thread/eb5cc524-e70d-4868-ab97-1c48fa347505, HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase key is used in new OSes.
Is this procedure works for win 2008 server as well ?
if not then, can anyone please provide the steps in detail.
This isn’t a support forum. Try the libguestfs or virt-tools mailing lists.
Pingback: New in virt-v2v | Richard WM Jones