Thursday, November 24, 2016

Windows Driver Architecture

Let's familiarize ourselves with concepts and terms used extensively with Windows Drivers. I have shared the links to the sources of information for details and tried to keep it brief here to help us speed up.

Let's start with defining drivers.
From the MSDN, "In the most fundamental sense, a driver is a software component that lets the operating system and a device communicate with each other."

The statement itself helps us deduce a lot about drivers:

  • It's software.
  • It sits between the operating system and the connected device.
  • It serves to communicate between the OS and the hardware.

So, the Windows kernel does not directly interact with the device. It depends on drivers to perform hardware-specific tasks, e.g. detecting the attached devices, mediating communication with them, and exposing them to the application by providing an interface.

Essentially, in the larger context, the driver has two interfaces, one which communicates with the OS and the other that knows how to communicate with the device hardware.

Think of it as follows:


Expanding the definition



It will make drivers pretty complex and cumbersome to implement if it's going to do all the business of detecting the device attached to it, handle all its primary functions, and even auxiliary functions like encrypting and decrypting the flow of data to and from the device.

So, Let's divide the work between several drivers and implement them in a stack, as follows:



Implemented as Driver Stack



For a given I/O request, several drivers, layered in a stack, participate in the request. Thus, not all the drivers communicate directly with the device. Keep this figure in mind, and we will discuss and look into it more in our section "Device Objects and the Device Stack".

To better understand how the driver works, let's try to understand how drivers fit in the system.

Core Windows Architecture

This section follows closely with the information given in the book "Developing Drivers with the Microsoft Windows Driver Foundation by Penny Orwick."

Windows system architecture is a layered architecture with applications at the top and hardware at the bottom divided into User Mode and Kernel Mode.

All Input/output (I/O) requests are packet-driven I/O, which utilizes I/O request packets (IRPs) and asynchronous I/O. These are passed between the system and the driver and from one driver to another in the stack.


The following figure is an oversimplified architectural diagram of Windows, showing how drivers integrate into the overall architecture.




Let's look into the key components given in the diagram. They are essential, and as we progress through our understanding of the drivers, we will see how the driver integrates into the overall architecture. 

Applications and Windows API

Consider getting a copy of "Windows via C/C++by Jeffrey Richter, Christophe Nasarre". The book covers the building blocks of the Windows application layer and how the application uses the resources provided by the operating system. The book helps to understand how the applications and drivers interact. It's a great book and is available in the Kindle version.

Applications run in the user mode and cannot directly call in the services of drivers that run in kernel mode (though a bit of generalization since UMDF drivers run in User mode).

Windows provides a documented interface to the application called Windows API or simply WinAPI. These APIs define the interface between the operating system and an application. The application uses these APIs to issue I/O requests, which use appropriate Windows components to pass the request to its kernel-mode component.

User Mode and Kernel Mode.

Windows operating system divides into two main operating modes: User mode and Kernel Mode.

User Mode
Kernel Mode
Applications, System defined processes, and DLLs.
Core Operating system components: Executive services, Kernel Driver, Kernel, and Hardware Abstraction Layer.
Runs in a restricted environment and cannot directly access hardware or reference memory.
Full and unrestricted access to the underlying hardware. Can execute any CPU instruction and reference any memory address.
The application has a private virtual address space and a private handle table. Because an application's virtual address space is private, one application cannot alter data that belongs to another application. 
All code that runs in kernel mode shares a single virtual address space. This means that a kernel-mode driver is not isolated from other drivers and the operating system itself.
The crash is limited to application.
Crash can cause system fault or BSOD.

Kernel Subsystem

NTOSKRNL.EXE contains the kernel subsystem that makes up the low-level kernel-mode portion. These subsystems handle much of the core Windows functionality like I/O, object management, power management, security and process management. There are several kernel subsystems in Windows operating system like:


Let's look into some subsystems and how they interact with the drivers:

I/O Manager
IO Manager facilitates communication between applications and the concerned driver. The I/O manager receives I/O requests from user mode, translates them into IRPs and passes them to the appropriate driver. It later gets a completed IRP from the driver and passes and data back to user mode and to the application that issued the request.

PnP Manager
Handles Plug and Play tasks such as enumerating the devices attached to the bus, constructing devices stack for the device, and handling the process of adding or removing the devices while the system is running.
Plug and Play service running in the user mode forms a significant portion of PnP Manager. It handles the often complex tasks of installing the appropriate drivers, notifying services and applications of the arrival of new devices, and displaying GUI to the user.

Power Manager
Power Manager handles the power events (power-off, stand-by, hibernate, etc.) generated during the computer's power state changes.

Drivers and Devices

The drivers provide the interface between the kernel subsystem and their devices. When the user application wants to initiate the communication or data transfer to the end device, it calls in well-defined APIs by the Windows OS. It, in turn, invokes the appropriate kernel subsystems that receive the request and structures data into a well-defined IRP structure. Later, the driver receives these I/O requests and processes and communicates with the devices. Any data output from the device passes back to the kernel subsystem that generated the request. 
Drivers also handle I/O requests directly generated from kernel subsystems such as PnP IRPs and Power IRPs to handle tasks such as preparing the device for removal or hibernation.

Let's dive into the "Device Objects and the Device Stack" in the upcoming blog.

Sources referred and followed:

No comments:

Post a Comment