Section 10.5. Communicating with the Kernel


10.5. Communicating with the Kernel

User programs communicate with kernel components frequently through system calls. Besides traditional system calls, Mac OS X provides other mechanisms to allow user programs to have a more direct communication with kernel componentsin particular, for low-level access to hardware.

One of the mechanisms is the I/O Kit Device Interface mechanism. A device interface is a user-space entity (say, a library) that user programs can call to access a device. Communication from user programs goes through the device interface to a kernel-resident user client, which in turn dispatches it to the device. From the kernel's standpoint, the user client is a driver whose class derives from IOService. Each user client instance represents a user-kernel connection. Note that user clients are not supported by all drivers.

A device interface is a plug-in interface conforming to the Core Foundation plug-in model.


Through the I/O Kit Device Interface mechanism, user programs can communicate with a driver or nub in the kernel and can therefore access devices, manipulate their properties, and use the associated I/O Kit services. As is typical of finding I/O Registry objects, a user program creates a matching dictionary containing one or more properties of the device it wishes to access using the Device Interface mechanism. For example, a match criterion could seek all FireWire mass-storage devices. This process is termed device matching. We saw in Section 10.2.11 that driver matching is performed by the I/O Kit during bootstrapping and results in the population of the I/O Registry. In contrast, device matching results in the I/O Registry being searched for objects that already exist (corresponding to drivers that are already loaded).

An application communicating with a device through its device interface can be seen as a user-space driver for that device.


Specification of matching criteria involves providing key-value pairs that identify one or more devices or servicessay, by describing some of their properties. The key-value pairs are encapsulated in a matching dictionary, which is essentially a reference to a Core Foundation CFMutableDictionary object. The I/O Kit framework provides functions such as IOServiceMatching(), IOServiceNameMatching(), IOOpenFirmwarePathMatching(), and IOBSDNameMatching() to create matching dictionaries. Given a matching dictionary, devices can be looked up in the I/O Registry using functions such as IOServiceGetMatchingService(), IOServiceGetMatchingServices(), and IOServiceAddMatchingNotification(). The latter also installs a notification request of new IOService objects that match. When one of these functions is called, the I/O Kit compares the values in the provided matching dictionary against the properties of nodes in the I/O Registry.

The I/O Kit defines several keys that can be used in matching dictionaries. Additional, family-specific keys are usually available in device families.


After finding a device, a program communicates with it using functions from the I/O Kit framework. Functions that communicate with the I/O Kit require the I/O Kit master port, which can be retrieved by using IOMasterPort(). Alternatively, the constant kIOMasterPortDefault can be specified to cause the I/O Kit framework to look up the default master port.

Another user-kernel communication mechanism is available through device files, which are rather ubiquitous on Unix-style systems. The I/O Kit automatically supports the device file mechanism for mass-storage and serial communications devices. On discovering such a device, besides configuring the usual stack of appropriate drivers, the I/O Kit creates an instance of a user client objectan IOMediaBSDClient or IOSerialBSDClient. The user client instance calls on the device file system (devfs) module to create the appropriate device file nodes. Since devfs is normally mounted under the /dev/ directory, these device nodes are visible within that directoryfor example, /dev/disk0 and /dev/cu.modem.

Similar to the case of a device interface, the kernel-resident user client in this case sits between the kernel entity representing the device and the user-space program that uses the /dev node to access the device.

The name of the /dev node corresponding to a device can be retrieved from the I/O Kit using device matching functions. The node's path is a property in the I/O Registry.





Mac OS X Internals. A Systems Approach
Mac OS X Internals: A Systems Approach
ISBN: 0321278542
EAN: 2147483647
Year: 2006
Pages: 161
Authors: Amit Singh

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net