Device Management

From Soma-notes

Disclaimer

The notes provided below strive to follow the lecture as given in class. I would suggest conducting open source searches on topics below in addition to referencing the text as much of the material is not touched on by the author.


Device Drivers

A driver is a small piece of software that allows an operating system or other program to interact with a hardware device. Applications generally have an API with high level commands. In contrast, a piece of hardware may require very explicit directions. A driver acts as a proxy and converts high level commands into commands understood by the underlying piece of hardware.


In Windows

In Windows, a device can be represented as one or more device objects. These device objects serve as the target for the operations on the device in question. Device objects do not have to represent physical hardware. Software only drivers must still have device objects in order to represent a target.

Detailed information about the Windows driver architecture can be found at the MSDN [1].

Categories

Windows drivers can be broken into three categories:

High Level
High level drivers are usually file system drivers and are dependent on intermediate and Lowest Level drivers.
Intermediate Level
Intermediate Level Drivers may control specific peripheral devices on an I/O bus and depend on Lowest Level drivers.
Lowest Level
Lowest Level Drivers control an I/O bus to which a specific peripheral is connected (different than above).

Driver Signing

Windows device drivers are typically written by third parties such as hardware vendors. Microsoft employs a digital signature policy system in order to exercise control over device drivers for the Windows OS. Hardware drivers developed for Windows (particularly x64 based systems) must be validated and digitally signed by Microsoft as part of the Windows Logo Program. On 64 bit systems, drivers require Kernel Mode Code Signing (KMCS) in order to be loaded in kernel mode. Microsoft claims that digital signing allows administrators and end users to verify that a legitimate publisher has created the driver being loaded. However, it has been argued that users are fundamentally no longer in control of their operating system.

Video cards need to be fast, and therefore very tightly coupled with the kernel. How do you make a video card that won’t play things that aren’t allowed like pirated media? One way is to add some code into the video card driver that checks for an attribute or pattern in the media being played. However, users wanting to play pirated content could get around this using a hacked device driver. But, this is where Windows driver signing comes into play. Case in point, if ATI and Nvidia want to support HDMI, they must implement High-Bandwidth Digital Content Protection (HDCP) which protects against pirated content.

Microsoft's digital driver signing has been criticized as too intrusive and part of a larger, aggressive anti-piracy initiative.

Hybrid Kernel and Problems

As stated above, many drivers for Windows are written by hardware manufacturers. Typically, Microsoft supplies an API and the driver developers must adhere to it. However, the quality of the driver produced can sometimes be questionable. In Windows Vista, many drivers that used to sit at the kernel level now sit outside the microkernel. This design is called a hybrid kernel which is not a true microkernel because most of the system components run in the same address space as the kernel consistent with monolithic kernel designs. This design should help to reduce the number of system crashes due to driver failures. This additional dependability brings with it three new problems:

Performance Issues
Drivers that exist outside of the kernel cause context switching. As discussed in an earlier lecture, this introduces performance hits.
Reduced Access
As an example, if you experience a hard disk failure, you may have to log in from another machine to get up and running again.
Shared Underlying Resources
Hardware devices are not independent entities. If one hardware device misbehaves it can make life hard to for other devices. In modern computer systems where devices can talk to each other, if a device goes rogue, it can saturate system buses or start overwriting RAM.

In Linux

On Linux, device drivers map to character devices or block devices which are special files. If you want to talk to a device in Unix, you can generally read/write to a file representing the device. A file at the OS level is generally just a byte stream. Why not represent a driver as multiple files? On Linux, those files usually reside in the /proc or /sys directories and appear to be 0 length files with strange permissions. These directories don’t correspond to persistent data but to kernel state. The exception is networking where device drivers may map to a network interface.

Using files as device drivers raises the question, how do you differentiate data from device commands? Commands are sent to a target device in-band using escape characters or special characters to distinguish commands from data.

Character Devices

Data in character devices is stored and accessed sequentially in arbitrary character length chunks. These devices do not implement the buffering mechanisms found in block devices.

Block Devices

Data in block devices is accessed randomly in fixed size chunks(blocks). Blocks are cached because I/O operations are inherently slow. Cached blocks get stored in fixed length buffers containing one or more blocks that are being read from the block device or written to it. If data can be found in this buffer cache then it does not need to be read from the physical block device, for example a hard disk, and access to it is much faster.

Buffer management must be done with care. Dirtying a file can occur when more memory is allocated to a buffer than is actually needed. A typical scenario for this to occur is streaming a file.

Problems

In Linux, you can write your own device drivers. However, when a new Kernel comes out, you may not be able to run your device drivers. Linux developers almost go out of their way to change their APIs (non application APIs) where as Microsoft maintains a very stable API. Linux kernel developers don’t want to be limited by backwards compatibility. To avoid this loss of functionality, drivers should be “in-tree” which means part of one of a distro and officially supported. Driver developers ask for device specifications and write a device driver that covers several similar devices and make it in-tree. This works well for most devices except bleeding edge hardware. Early hardware adopters may have to wait up to six months to get drivers that work with a new device.