Tip: Install a device driver in a Windows VM

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.

About these ads

11 Comments

Filed under Uncategorized

11 responses to “Tip: Install a device driver in a Windows VM

  1. Yaniv

    What about the .INF and the .CAT? Especially the .CAT is important, as Windows has to verify the driver is WHQL-signed.

    • rich

      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.

  2. Paolo Bonzini

    Yeah, the boot loader cares about the embedded signatures but not about the catalog.

  3. 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

  4. Buck

    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

  5. StepBP

    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.

  6. pratik07055

    Is this procedure works for win 2008 server as well ?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s