Introduction
Driver is a very important piece of software that provides a way for a particular hardware to interact with a particular Operating System. Development of device drivers is quite a daunting task. It is a complicated and fastidious activity that demands immense expertise and patience. Microsoft knew that drivers had to be writable in a higher-level language like C, in order to be code-compatible for different hardware systems. To meet these needs, Microsoft created the Windows Driver Model (WDM).WDM drivers are compiled using the DDK, they are written in C, and they follow exacting specifications that ensure they can be executed on any windows system. The Windows platform DDK comes with header files, library files, and a command-line compiler that can be used to write device drivers in C or C++. There is no graphical interface to the DDK compiler.
Windows Driver Architecture
The Windows driver architecture provides an extensible interface between the user and kernel layers called the Windows I/O manager. The I/O Manager API includes functions for communicating with device drivers using data structures called I/O Request Packets (IRPs).
To improve portability, some implementations isolate the I/O Manager calls in a separate layer as illustrated below, while other implementations make I/O manager calls throughout the driver code.
The communication process between the user driver and the device driver includes the following steps:
Step1- The user driver opens a reference to the device by using the Windows API function CreateFile.
Step2- The user driver sends a control code (command) to the device driver through the Windows API function DeviceIOControl.
Step3- The Windows I/O manager receives the control code, creates an IRP, and routes the IRP to the device driver.
Step4- The device driver receives the IRP. Based on the control code, it performs the operation requested by the user-level driver. The device driver accesses the hardware to complete the requested operation. Any data returned by the device is inserted in the IRP and sent back to the user driver via the I/O manager.
Step5- When the application is finished, it requests the user driver to close the device. The user driver closes the device reference by calling the Windows API function CloseHandle.
In the Windows driver architecture, devices are treated as file resources, providing a common abstraction model for the user driver. Simple direct access to the device driver can be achieved by calling the Windows API functions ReadFile and WriteFile (instead of DeviceIOControl). There are many additional Windows API functions that can be used to communicate with device drivers.
Device Driver APIs
Windows driver APIs are event-driven: the driver code executes only when some event happens: either when user applications want something from the device, or when the device has something to tell to the OS.
a. Initialization
On Windows, drivers are represented by a DriverObject structure which is initialized during the execution of the DriverEntry function. This entry point also registers a number of callbacks to react to device addition and removal, driver unloading, and handling the incoming IRPs. Windows creates a device object when a device is connected, and this device object handles all application requests on behalf of the device driver.
b. Naming and claiming devices
Windows device driver is notified about newly connected devices in its AddDevice callback. It then proceeds to create a device object used to identify this particular driver instance for the device. Depending on the driver kind, device object can be a Physical Device Object (PDO), Function Device Object (FDO), or a Filter Device Object (FIDO). Device objects can be stacked, with a PDO in the bottom.
Device objects exist for the whole time the device is connected to the computer. DeviceExtension structure can be used to associate global data with a device object.
Device objects can have names of the form \Device\DeviceName, which are used by the system to identify and locate them. An application opens a file with such name using CreateFile API function, obtaining a handle, which then can be used to interact with the device.
However, usually only PDOs have distinct names. Unnamed devices can be accessed via device class interfaces. The device driver registers one or more interfaces identified by 128-bit globally unique identifiers (GUIDs). User applications can then obtain a handle to such device using known GUIDs.
c. Exchanging data
Windows support three ways of transferring data between user-level applications and kernel-level drivers:
- Buffered Input-Output which uses buffers managed by the kernel. For write operations the kernel copies data from a user-space buffer into a kernel-allocated buffer, and passes it to the device driver. Reads are the same, with kernel copying data from a kernel buffer into the buffer provided by the application.
- Direct Input-Output which does not involve copying. Instead, the kernel pins a user-allocated buffer in physical memory so that it remains there without being swapped out while data transfer is in progress.
- Memory mapping can also be arranged by the kernel so that the kernel and user space applications can access the same pages of memory using distinct addresses.
Driver IO modes on Windows
Support for Buffered IO is a built-in feature of WDM. The buffer is accessible to the device driver via the AssociatedIrp.SystemBuffer field of the IRP structure. The driver simply reads from or writes to this buffer when it needs to communicate with the userspace.
Direct IO on Windows is mediated by memory descriptor lists (MDLs). These are semi-opaque structures accessible via MdlAddress field of the IRP. They are used to locate the physical address of the buffer allocated by the user application and pinned for the duration of the IO request.
The third option for data transfer on Windows is called METHOD_NEITHER. In this case the kernel simply passes the virtual addresses of user-space input and output buffers to the driver, without validating them or ensuring that they are mapped into physical memory accessible by the device driver. The device driver is responsible for handling the details of the data transfer.
Windows Driver Development Environment
A. Windows Driver Kit
Windows is a closed-source operating system. Microsoft provides a Windows Driver Kit to facilitate Windows device driver development by non-Microsoft vendors. The kit contains all that is necessary to build, debug, verify, and package device drivers for Windows.
Windows Driver Model defines a clean interface framework for device drivers. Windows maintains source and binary compatibility of these interfaces. Compiled WDM drivers are generally forward-compatible: that is, an older driver can run on a newer system as is, without being recompiled, but of course it will not have access to the new features provided by the OS. However, drivers are not guaranteed to be backward-compatible.
B. Build system for device drivers
Windows Driver Kit adds driver development support for Microsoft Visual Studio, and includes a compiler used to build the driver code. Developing Windows device drivers is not much different from developing a user-space application in an IDE. Microsoft also provides an Enterprise Windows Driver Kit, which enables command-line build environment similar to the one of Linux.
C. Documentation support
Windows has excellent documentation support for driver development. Windows Driver Kit includes documentation and sample driver code, abundant information about kernel interfaces is available via MSDN, and there exist numerous reference and guide books on driver development and Windows internals.
D. Debugging support
Windows has logging facilities that can be used to trace-debug driver code. On Windows one would use DbgPrint function for this Windows supports interactive debugging via its kernel-level debugger WinDbg. This requires two machines connected via a serial port: a computer to run the debugged kernel, and another one to run the debugger and control the operating system being debugged. Windows Driver Kit includes debugging symbols for Windows kernel so Windows data structures will be partially visible in the debugger.
OdiTek’s Expertise on Device Driver Development
Our expertise on developing and customizing Windows device drivers like Camera device drivers etc. has helped customers release custom solutions. Like Linux Device driver development, we have the core expertise to produce development solutions for Windows device drivers as well.
We have an ideal mix of young talent complemented by a mature research group that undertakes the activity of developing device drivers. Based on precise understanding of how drivers interact with the operating system or kernel, our team develops drivers for Microsoft Windows and Linux.
OdiTek also holds the ace when it comes to customizing the device drivers. We offer modifications and porting services for existing device drivers to be compatible with new operating or hardware platforms. We foster a dynamic development environment that follows stringent quality checks and source code integrity guidelines.
We can also develop with speed the drivers that can be suitable for cameras, audio devices, printers, scanners, monitors, storage devices, keyboards, mouse, modems and network cards. Whether it is kernel level programming for embedded solutions or interfacing peripherals, OdiTek offers dedicated efforts that guarantee quality output.
For more information on Windows device driver development & Customization, Please drop an email to- info@oditeksolutuons.com