The I/O Kit Model

The I/O Kit is an object-oriented framework, thus it requires a language that provides an object-oriented programming abstraction. Apple chose to implement the I/O Kit in the C++ language, and consequently, drivers that are written for Mac OS X are developed in C++.

While the choice of C++ for driver development is unique among operating systems, it reflects the modern nature of Mac OS X. The initial version of Mac OS X was released in 2001, and Apple took the opportunity to design a completely new model for driver development. The choice of C++ reflects the state of both computer hardware and compilers when the I/O Kit was designed.

The choice of an object-oriented language has considerable advantages. Hardware in a computer system is, by its nature, an interconnected series of devices connected via a number of different buses. For example, a USB device may be connected to the internal USB hub of a keyboard, which itself is connected to the USB port on an iMac. Internally, the USB port is handled by a USB controller chip on the iMac's motherboard, which is connected to the motherboard's chipset controller via an internal PCI bus. By adopting an object-oriented driver model, the I/O Kit is able to mirror this same hardware connection through the driver objects.

The role of a driver is to enable the operating system—and ultimately the user—to take advantage of the services that are implemented by hardware. The operating system helps the driver by loading the driver when its hardware device is present, providing the driver with a way to access and interact with its hardware device, and by providing access points for the driver to plug its own services into the operating system.

images Note The I/O Kit uses the term “nub” to describe a driver that provides services to other drivers. For example, the driver of a USB hub would be a nub because it provides services to the drivers of the USB devices that connect to it.

The choice of an object-oriented design serves the I/O Kit well. Each driver is implemented as a C++ class, which allows the I/O Kit to instantiate a new driver object for each instance of the hardware device present on the system. The driver's hardware device is accessed through an object known as the driver's “provider,” which is provided to the driver at initialization. The I/O Kit will use a provider class that is appropriate for the hardware bus used by the device. For example, a USB device will have a provider class that is an instance of an IOUSBDevice, whereas a driver for a PCI card will have a provider class that is an instance of an IOPCIDevice. The different capabilities of these bus interfaces are abstracted by the different provider class types. For example, USB devices have a number of endpoints that data is transferred to or read from, so the IOUSBDevice class contains methods for reading or writing a data buffer to a specified endpoint. On the other hand, a PCI card is accessed by mapping a set of registers into the kernel's address space, which can then be read from and written to by the driver the same way in which it writes to any other memory address.

Lastly, drivers need a way to provide their services to the rest of the operating system. This is perhaps the area where the object-oriented design of the I/O Kit shines. The main class of the driver can be implemented as the subclass of one of the specialized classes provided by the I/O Kit for certain types of driver. For example, a driver that implements a serial port will subclass the standard IOSerialStreamSync class. Similarly, a driver that implements an audio output device will subclass the IOAudioDevice class.

The advantage of implementing a driver by subclassing is that your driver inherits the behavior and implementation from the parent class. There are certain operations that are common to every serial port and to every audio device, and this behavior is implemented by the superclass, saving driver developers from having to write boilerplate code. Developers can then concentrate on code that is specific to their particular hardware device. The superclass will call the driver when a device-specific action is required.

If you've implemented a driver for any other operating system, you have no doubt had to implement a dispatch routine that usually takes the form of one large switch statement in order to handle all the possible requests that the operating system may make and then calling the appropriate function in your driver that implements that request. The I/O Kit takes a different approach. Driver requests take the form of method calls. The driver simply needs to implement or override methods that are provided by its superclass. These methods are specific to the driver type. For example, a serial driver is concerned with transmitting bytes and receiving bytes over the serial port, so the IOSerialStreamSync class provides pure virtual methods enqueueData() and dequeueData() to be implemented by the subclass when these actions need to be performed.

For a specialized device, the I/O Kit may not provide a suitable superclass. For example, there is no suitable superclass provided by the I/O Kit to implement a driver for a specialized medical imaging device. The driver for such a device would be implemented by a class that subclasses from the generic IOService class. The IOService provides methods to manage the driver's lifecycle, including initialization and destroying the driver object.

Lastly, a driver may provide an interface to user space applications. In I/O Kit terminology, this is handled by implementing a class known as a “user client.” The user client is a custom class implemented by the driver that subclasses the IOUserClient class. Whenever an application opens a connection to the driver, the I/O Kit instantiates a new user client object that handles all the requests coming from that application's connection to the driver. When the application closes that connection to the driver, or the application terminates (or crashes), the user client is destroyed. If an application opens multiple connections to the driver, the I/O Kit will instantiate as many user client objects as there are connections made.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.129.211.165