Mac OS X Internals: A Systems Approach
10.1. A Driver down the Memory Lane
In commercial operating systems, the majority of third-party kernel programming pertains to device drivers. A driver can be informally defined as a flow of controlsay, a threadthat manages one or more devices. Given the variety of operating systems and device driver models in existence, the control flow could be in the kernel or in user space, and the device could be a physical device or a software (pseudo) device. From an implementation standpoint, a device driver in a typical modern Unix system is a software component that groups functions corresponding to one or more related devices. It is common for device drivers to be dynamically loadable modules that can be unloaded when not used, in order to lower resource consumption. It is also usually possible to compile a device driver into the kernel, if necessary. 10.1.1. Driver Programming Considered Difficult
Historically, it has been considered rather difficult to write device drivers for an operating system. One reason was that many operating systems did not have well-defined driver architectures. This has improved, as most modern systems have driver architectures and environments that emphasize modularity and, to varying degrees, code reuse. Another reason, which continues to remain valid, is that drivers typically execute in the kernel environment, which is inherently more complex and fragile than user space. The Mac OS X driver architecture is especially helpful in this regard, since it supports versatile mechanisms to access devices from user space. In particular, the architecture supports user-space drivers. For example, devices such as keyboards, mice, printers, scanners, digital still cameras, and digital videocameras can be driven by user-space programs on Mac OS X. 10.1.2. Good Inheritance
The Mac OS X driver architecture is implemented by the I/O Kit, which is a descendent of NEXTSTEP's Driver Kit. The latter was a package of object-oriented software and tools that helped the programmer write device drivers in a modular fashion. The Driver Kit's goal was to make writing and debugging drivers almost as easy as writing and debugging regular NEXTSTEP applications. It aimed to generalize the software involved in drivers, so that writing them would require less time and effort. The underlying observation was that although drivers may drive vastly different devices, they still have several common aspects and requirements. The Driver Kit treated drivers as essential components of the I/O subsystem, since peripherals required for various types of I/O in a computer system were also driven by drivers. Moreover, drivers for loosely related devices might be very close to each other in implementation. The commonalities could be offered as libraries for use by driver developers. The Driver Kit used Objective-C as its programming language. 10.1.3. Everything Is a File
Typical Unix systems provide a file-system-based user interface to devicesa user-space process addresses a device through device special files (or simply device files) that conventionally reside in the /dev/ directory. Older systems had a static /dev/, wherein the constituent device files were explicitly created or deleted, and device major numbers were statically assigned. Newer systems, including Mac OS X, manage devices more dynamically. For example, the Mac OS X device file system allows device files to be dynamically created or deleted and major numbers to be automatically assigned on device file creation. The device files in the earliest versions of UNIX were hardcoded into the kernel. For example, /dev/rk0 and /dev/rrk0 were the block and character devices, respectively, representing the first moving-head RK disk drive attached to the system. /dev/mem mapped the core memory of the computer into a file. It was possible to patch the running system using a debugger on /dev/mem. When such a file was read from or written to, the underlying device was activatedthat is, the corresponding kernel-resident functions were invoked. Besides data I/O, control operations could also be performed on device files. The basic concepts of device files have remained largely the same as UNIX and its derivatives have evolved. Mac OS X provides device files for storage devices,[1] serial devices, pseudo-terminals, and several pseudo-devices. [1] As we will see in Section 11.3, storage-related Unix-style devices on Mac OS X are implemented by the I/O Kit. 10.1.4. There Is More to Extending the Kernel Than Driving Devices
Besides device drivers, several other types of code can extend the kernel. Loadable kernel components on Mac OS X include file systems, file system authorization modules (see Section 11.10), storage device filters, BSD-style sysctl variables, and network extensions. Beginning with version 10.4, Mac OS X provides stable kernel programming interfaces (KPIs) for these various types of kernel components. |
Категории