Adding a driver to a test image
This topic shows you how to create a feature and add it to a test image.
Process overview – adding a driver feature to a test image
To create a feature that contains a driver and add it to a test image, complete the following steps.
Create a test KMDF driver
Generate the driver package
Create a feature manifest file that references the package
Add the feature to the OEMInput.xml file
Generate, sign, and flash the image to the device
Verify that the KMDFDriver1 is on the device
Verify that the driver loads using Windows debug
The following diagram summarizes the packaging and image generation elements that are used to add the driver to the device.
Walkthrough – adding a driver to a test image
This topic describes the steps that you need to perform to add a driver to a test image. Before you can start this walkthrough, you must first create a simple KMDF driver.
This walkthrough assumes that you named the project KmdfDriver1.
Create a test KMDF driver
To create a test KMDF driver, complete the following steps.
In the Solution Explorer window, expand KmdfDriver1 and then expand the Source Files Folder.
Edit the "Driver.c" file by clicking it.
Right after the variable declaration section, add the IoReportRootDevice routine as show below. The IoReportRootDevice routine reports a device that cannot be detected by a PnP bus driver to the PnP Manager. This allows the software-only driver to remain loaded.
... { WDF_DRIVER_CONFIG config; NTSTATUS status; WDF_OBJECT_ATTRIBUTES attributes; // // IoReportRootDevice routine reports a device that cannot be detected by // a PnP bus driver to the PnP Manager. This allows our software-only // driver to remain loaded. IoReportRootDevice(DriverObject); // // Initialize WPP tracing. // WPP_INIT_TRACING( DriverObject, RegistryPath ); TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry"); ...
Save Driver.c.
To build your driver and create a driver package, choose Build Solution from the Build menu. Visual Studio displays the build progress in the Output window. (If the Output window is not visible, choose Output from the View menu.)
To view the built driver package, navigate in Windows Explorer to your KmdfDriver1 folder, and then to ARM\Win8.1Debug\. This directory contains the following files:
KmdfDriver1.sys - A kernel-mode driver file.
KmdfDriver1.inf - An information file that Windows uses to install the driver.
KmdfDriver1.pdb – A file that contains the debug symbols that will be used for debugging.
KmdfDriver1.cat - A catalog file that is not used in this walkthrough.
There are also co-installer files for the Windows Driver Frameworks (WDF) that will not be used with Windows Phone.
Because of the differences in Windows 10 Mobile INF files, we will not use the desktop INF file that is generated by Visual Studio.
; ; KmdfDriver1.inf ; [Version] Signature="$WINDOWS NT$" Class=System ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} Provider=%MSFT% DriverVer=11/01/2012,1.00.00.00 BootCritical=1 [DestinationDirs] DefaultDestDir = 12 [Manufacturer] %StdMfg%=KMDFDriver1_DevDesc, NTARM, NTx86 ;******************************* ;** models section (required) ** ;******************************* ; For ARM platforms [KMDFDriver1_DevDesc.NTARM] ; DisplayName Section DeviceId ; ----------- ------- -------- %KMDFDriver1_DevDesc%=KMDFDriver1, Root\KMDFDriver1 ; For Win2K+ [KMDFDriver1_DevDesc.NTx86] ; DisplayName Section DeviceId ; ----------- ------- -------- %KMDFDriver1_DevDesc%=KMDFDriver1, Root\KMDFDriver1 ;******************************** ;* ddinstall section (required) * ;******************************** [KMDFDriver1.NT] CopyFiles=KMDFDriver1.NT.Copy [KMDFDriver1.NT.Copy] KMDFDriver1.sys ;-------------- Service installation [KMDFDriver1.NT.Services] AddService = KMDFDriver1, %SPSVCINST_ASSOCSERVICE%, KMDFDriver1_Service_Inst [KMDFDriver1_Service_Inst] DisplayName = %KMDFDriver1_DevDesc% ServiceType = %SERVICE_KERNEL_DRIVER% StartType = %SERVICE_SYSTEM_START% ErrorControl = %SERVICE_ERROR_NORMAL% ServiceBinary = %12%\KMDFDriver1.sys [Strings] SPSVCINST_ASSOCSERVICE= 0x00000002 MSFT = "Microsoft" KMDFDriver1_DevDesc = "KMDF Driver 1" SERVICE_KERNEL_DRIVER = 1 SERVICE_AUTO_START = 2 SERVICE_SYSTEM_START = 1 SERVICE_BOOT_START = 0 SERVICE_ERROR_NORMAL = 1
Sign the driver using the following commands:
C:>set SIGN_OEM=1 sign KMDFDriver1.sys
Generate a package that contains the driver
Generate a package that contains this driver by completing the following steps.
Create a directory called KMDFDriver1 and copy the KMDFDriver1.sys and KMDFDriver1.inf files that you created in Visual Studio, to that directory.
Create a text file named KmdfDriver1 .pkg.xml that contains the following package definition XML.
<?xml version="1.0" encoding="utf-8"?> <Package xmlns="urn:Microsoft.WindowsPhone/PackageSchema.v8.00" Owner="Contoso" OwnerType="OEM" ReleaseType="Test" Platform="DCD6000" Component="Phone.Test.BaseOS" SubComponent="KmdfDriver1" Partition="MainOS" BinaryPartition="false"> <Components> <OSComponent> <Files> <File Source="KmdfDriver1.sys" DestinationDir="$(runtime.system32)\drivers"/> </Files> </OSComponent> <Driver InfSource="KmdfDriver1.inf"> <Reference Source="KmdfDriver1.sys"/> </Driver> </Components> </Package>
You can update the owner and platform attributes to match the name of your organization name and the name of your device. These attribute changes will modify the name of the generated package.
Specify the Windows\System32\Drivers directory on the device using the $(runtime.system32) macro.
The next step is to generate the package by opening an administrator command prompt window.
Display the environment variables by typing SET in the administrator command prompt window. Look for WPDKCONTENTROOT to confirm that the build environment is properly configured. You should see that WPDKCONTENTROOT is set. On a Windows 64-bit PC, the path should look similar to the following.
... WPDKCONTENTROOT=C:\Program Files (x86)\Windows Kits\10
Generate the package using PkgGen. Provide the version number of 1.0.0.0. The /config parameter points to the location of the pkggen.cfg.xml file provided with the Windows DriverKit. The /hive parameter points to the location of the hive root.
C:\KmdfDriver1>PkgGen KmdfDriver1.pkg.xml /version:1.0.0.0 /variables:"HIVE_ROOT=%WPDKCONTENTROOT%\CoreSystem" /config:"%WPDKCONTENTROOT%\Tools\bin\i386\pkggen.cfg.xml"
If PkgGen creates the package successfully, it will display many lines of information as the registry entries are created based on the provided INF file. The last part of the output will be similar to the following.
... info: Import Log: : sto: Unloaded hive key '{bf1a281b-ad7b-4476-ac95-f47682 990ce7}C:/Users/User1/AppData/Local/Temp/gs5gvfgc.pou/windows/system32/config/S OFTWARE'. Time = 0 ms info: Import Log: : <<< Section end 2015/08/06 13:10:22.413 info: Import Log: : <<< [Exit status: SUCCESS] info: Import Log: : info: Import Log: : info: Import Log: : >>> [Unload Offline Registry Hive - DRIVERS] info: Import Log: : >>> Section start 2014/08/06 13:10:22.413 info: Import Log: : os: Version = 6.3.9600, Service Pack = 0.0, Suite = 0 x0100, ProductType = 1, Architecture = x86 info: Import Log: : cmd: PkgGen KmdfDriver1.pkg.xml /version:1.0.0.0 /var iables:"HIVE_ROOT=C:\Program Files (x86)\Windows Kits\10\CoreSystem" /con fig:"C:\Program Files (x86)\Windows Kits\10\Tools\bin\i386\pkggen.cfg.xml " info: Import Log: : sto: Closed hive key '{bf1a281b-ad7b-4476-ac95-f4768299 0ce7}C:/Users/User1/AppData/Local/Temp/gs5gvfgc.pou/windows/system32/config/DRI VERS'. info: Import Log: : sto: Unloaded hive key '{bf1a281b-ad7b-4476-ac95-f47682 990ce7}C:/Users/User1/AppData/Local/Temp/gs5gvfgc.pou/windows/system32/config/D RIVERS'. Time = 0 ms info: Import Log: : <<< Section end 2014/08/06 13:10:22.513 info: Import Log: : <<< [Exit status: SUCCESS] info: Import Log: : info: Building package '.\Contoso.Phone.Test.BaseOS.KmdfDriver1.spkg' info: Adding file 'KmdfDriver1.sys' to package '.\Contoso.Phone.Test.BaseOS.Kmdf Driver1.spkg' as '\windows\System32\drivers\KmdfDriver1.sys' info: Adding file 'C:\Users\User1\AppData\Local\Temp\5bgjkx3p.j01\reg.reg' to p ackage '.\Contoso.Phone.Test.BaseOS.KmdfDriver1.spkg' as '\Windows\Packages\Regi stryFiles\Contoso.Phone.Test.BaseOS.KmdfDriver1.reg' info: Adding file 'C:\Users\User1\AppData\Local\Temp\5bgjkx3p.j01\regMultiSz.rg a' to package '.\Contoso.Phone.Test.BaseOS.KmdfDriver1.spkg' as '\Windows\Packag es\RegistryFiles\Contoso.Phone.Test.BaseOS.KmdfDriver1.rga' info: Done package ".\Contoso.Phone.Test.BaseOS.KmdfDriver1.spkg" info: Packages are generated to . successfully
For more information about working with packages, see Creating packages.
Create a feature manifest file that references the package
Create a feature manifest file that will define a DRIVER1 OEM feature by completing the following steps.
Create a feature manifest file named OEMCustomAppFM.xml in the following directory.
%WPDKCONTENTROOT%\FMFiles
Define the DRIVER1 feature by adding the following XML to the OEMCustomDriverFM.xml file. Update the package name to match the name of the package file generated in the previous step.
<?xml version="1.0" encoding="utf-8"?> <FeatureManifest xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns="https://schemas.microsoft.com/embedded/2004/10/ImageUpdate"> <!-- DRIVER1 FM File 7/31/2014 --> <Features> <OEM> <PackageFile Path="C:\KmdfDriver1\" Name="Contoso.Phone.Test.BaseOS.KmdfDriver1"> <FeatureIDs> <FeatureID>DRIVER1</FeatureID> </FeatureIDs> </PackageFile> </OEM> </Features> </FeatureManifest>
For more information about feature manifests, see Feature manifest file contents.
Add the feature to the OEMInput.xml file
Add the DRIVER1 feature to the OEMInput.xml file by completing the following steps.
This walkthrough assumes that you have an existing, functional test OEMInput file that enables TShell. For more information about creating test images, see Building and flashing images. For more information about specifying optional features, see Optional features for building images.
Confirm that that you are using a test image that has debugging enabled. For more information, see Optional features for building images.
Edit the OEMinput.xml file to include the OEMCustomAppFM.xml feature manifest file that you created in the previous step. The XML will be similar to the following.
... <AdditionalFMs> ... <AdditionalFM>%WPDKCONTENTROOT%\FMFiles\OEMCustomDriverFM.xml</AdditionalFM> </AdditionalFMs>
In the <Features> section of the OEMInput.xml file, add the new DRIVER1 feature to the list of existing features.
<Features> <Microsoft> ... </Microsoft> <OEM> ... <Feature>DRIVER1</Feature> </OEM> </Features>
Generate, sign, and flash the image to the device
Complete the following steps to generate, sign, and flash the image.
Generate the image using ImgGen and the OEMInput.xml file that you customized in the previous step.
C:\>ImgGen Flash.ffu OEMInput.xml "%WPDKCONTENTROOT%\10\MSPackages"
Before you can sign images, you must first install the test OEM certificates on the PC by following the steps in Set up the signing environment.
Sign the generated catalog using the Sign.cmd with the /pk option.
C:\> Set SIGN_OEM=1 C:\> Sign.cmd /pk TestSigned.cat
Sign the FFU with the signed catalog file using ImageSigner.
C:\> ImageSigner Sign Flash.FFU Flash.Cat
Flash the image to the phone using FFUTool.
C:\> FFUTool –Flash Flash.ffu
For more information about generating and flashing images, see Building and flashing images.
Verify that the KMDFDriver1 is on the device
Verify that the KMDFDriver1 is present on the device by using TShell.
Configure a TShell connection to test the image.
Establish a connection to the device using the Open-device TShell command. Provide the MAC address of the device.
PS C:\> Open-device 001122334455
Confirm that the KMDFDriver1 is on the device by using the Dir-Device TShell command. The short form of the command, DirD, is shown.
PS C:\> DirD \KMDFDriver1.sys /s
You should see output similar to the following.
Volume in drive C is MainOS Volume Serial Number is 965E-2180 Directory of C:\windows\system32\DRIVERS 04/21/2014 05:23 PM 8864 KMDFDriver1.sys 1 File(s) 8864 bytes Total Files Listed: 1 File(s) 8864 bytes 0 Dir(s) 409976832 bytes free
Enable debug output for KdPrint(), KdPrintEx(), and DbgPrint() messages by setting a registry key. Set the registry key so that it is persistent across reboots (for non-retail images) by using the RegD Add TShell command.
DEVICE C:\ PS C:\Windows\system32> RegD Add "HKLM\SYSTEM\ControlSet001\Control\Session Manager\Debug Print Filter" /v DEFAULT /t REG_DWORD /d 0xFFFFFFFF The operation completed successfully.
Confirm that registry key was set by using the RegD Query TShell command.
DEVICE C:\ PS C:\Windows\system32> RegD Query "HKLM\SYSTEM\ControlSet001\Control\Session Manager\Debug Print Filter" HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Session Manager\Debug Print Filter DEFAULT REG_DWORD 0xffffffff
Verify that the driver loads using Windows debug
To view the driver load process, complete the following steps to set a debug statement in the driver and connect the device to the kernel debugger.
Open the driver project in Visual Studio.
Add a debug break statement in Driver.c right after the variable declaration section of the DriverEntry routine.
… WDF_DRIVER_CONFIG config; NTSTATUS status; WDF_OBJECT_ATTRIBUTES attributes; // Debug break statement to stop loading of OS // Debugger must be attached to allow the device to boot __debugbreak(); …
Warning
The debug break statement will stop the phone from booting unless a debugger is attached to the device.
Rebuild the project in Visual Studio.
If necessary, copy the updated .sys file to the directory that you will use to create to generate the package.
Then, repeat the steps described above to:
Generate an updated driver package.
Generate, sign, and flash the image.
Note
It is also possible to update the version of the driver by including the driver version in the INF file and then using the IUTool to deploy the updated driver to the phone. For more information about using IUTool, see IUTool.exe: Update packages on a phone. This process is similar to the process that is used to create a driver update. For more information about that, see Update a KMDF device driver.
Set up a KDNET over USB connection to the phone for debugging.
Start the Windows debugger.
windbg -k net:port=5000,key=1.2.3.4
After the device has booted, it will hit the break point and code execution will stop. The debugger will indicate that break point has been hit.
Set the symbol path to the location of the Windows Driver Kit symbols and reload the symbols.
.SYMPATH+ C:\SYMBOLS .reload /f
Set the source path to the location of your .c source code that you created earlier in Visual Studio.
.srcpath+ C:\KMDFDriver1\Source\
List the call stack by using the k command.
0: kd> k # Child-SP RetAddr Call Site 00 85679c68 90fd2abe KMDFDriver1!DriverEntry+0xa 01 85679ce0 90fd2b38 KMDFDriver1!FxDriverEntryWorker+0x6a 02 85679d00 81770990 KMDFDriver1!FxDriverEntry+0x18 *** ERROR: Symbol file could not be found. Defaulted to export symbols for ntkrnlmp.exe - 03 85679d10 818f8004 nt!SeTokenIsAdmin+0x1790 04 85679e10 8190d630 nt!KeFindConfigurationNextEntry+0x7c48 05 85679e68 8185719e nt!KeHwPolicyLocateResource+0x4698 06 85679e70 814c5e0c nt!IoReplacePartitionUnit+0x192 07 85679e80 81460172 nt!IoAllocateIrp+0x57c 08 85679ec8 00000000 nt!KiDispatchInterrupt+0x234a
The call stack is the chain of function calls that have led to the current location of the program counter. The top function on the call stack is the current function, and the next function is the function that called the current function, and so on.
Display symbol information associated with KMDFDriver1 using the x command.
0: kd> x KMDFDriver1!* 90fd4750 KMDFDriver1!WdfDriverGlobals = 0x88ff4de8 90fd4754 KMDFDriver1!WdfDriverStubDriverObject = 0x88fed768 90fd4004 KMDFDriver1!__security_cookie_complement = 0x568f867 90fd336c KMDFDriver1!__gsfailure_xdata_end = <unknown base type 80000013> 90fd33b4 KMDFDriver1!__memcpy_reverse_large_neon_xdata = <unknown base type 80000013> 90fd30c0 KMDFDriver1!WPP_c0dfc8e231dc218098dc0c2ed20d6e73_Traceguids = struct _GUID [1] 90fd30a0 KMDFDriver1!GUID_DEVINTERFACE_KmdfDriver1 = struct _GUID {e7a4cfb0-56d4-4234-bf60-fe627cb5e981} 90fd474c KMDFDriver1!WdfDriverStubDisplacedDriverUnload = 0x00000000 90fd3370 KMDFDriver1!memcpy_xdata_prolog = <unknown base type 80000013> 90fd3388 KMDFDriver1!__memcpy_forward_large_neon_xdata = <unknown base type 80000013> 90fd4758 KMDFDriver1!WdfDriverStubOriginalWdfDriverMiniportUnload = 0x00000000
List information about the modules on KMDFDriver1 by using the lm m command.
0: kd> lm m KMDFDriver1 v Browse full module list start end module name 90fd1000 90fd9000 KMDFDriver1 (private pdb symbols) c:\kmdfdriver1\KmdfDriver1.pdb Loaded symbol image file: KMDFDriver1.sys Image path: KMDFDriver1.sys Image name: KMDFDriver1.sys Browse all global symbols functions data Timestamp: Thu Jul 31 14:39:34 2014 (53DAB796) CheckSum: 000037D2 ImageSize: 00008000 Translations: 0000.04b0 0000.04e4 0409.04b0 0409.04e
Load the WDF driver extensions using the .load command.
.load C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\winext\Wdfkd.dll
Confirm that the WDF debug extension is loaded by using the !wdfkd.help WDK driver extension help command.
!wdfkd.help
Display information about the driver using the !wdfkd.wdfdriverinfo command.
0: kd> !wdfkd.wdfdriverinfo KMDFDriver1 ---------------------------------- Default driver image name: KMDFDriver1 WDF library image name: Wdf01000 FxDriverGlobals 0x90584008 WdfBindInfo 0x913d8008 Version v1.11 Library module 0x8283b528 ServiceName \Registry\Machine\System\CurrentControlSet\Services\Wdf01000 ImageName Wdf01000 ---------------------------------- Driver Handles is NULL
End the debugging session using the qd quit and detach command.
0: kd> qd