Cover
Contents at a Glance
Contents
About the Authors
About the Technical Reviewers
Acknowledgments
Introduction
Operating System Fundamentals
The Role of the Operating System
Process Management
Process Address Spaces
Operating System Services
Virtual Memory
Scheduling
Hardware and Drivers
Summary
Mac OS X and iOS
Programming APIs
Supported Platforms
64-bit Operating System
iOS
The XNU Kernel
Kernel Extensions (KEXTs)
Mach
Tasks and Threads
Scheduling
Mach IPC: Ports and Messages
Mach Exceptions
Time Management
Memory Management
Task Address Space
VM Maps and Entries
The Physical Map
VM Objects
Examining a Task's Address Space
Pagers
Memory Allocation in Mach
The BSD Layer
System Calls
Networking
File Systems
The Virtual File System
Unified Buffer Cache
The I/O Kit
The Libkern Library
The Platform Expert
Xcode and the Kernel Development Environment
Language of Choice: C++
Xcode
"Hello World" Kernel Extension
Loading and Unloading Kernel Extensions
Using Console to View Output
Summary
The I/O Kit Framework
The I/O Kit Model
Object Relationship
The Info.plist File
The Driver Class
IORegistryExplorer
The Kernel Library: libkern
OSObject
Container Classes
Summary
Interacting with Drivers from Applications
The I/O Kit Framework
Finding a Driver
Observing Device Removal
Modifying Driver Properties
State-Based Interaction
Summary
Memory Management
Types of Memory
CPU Physical Address
Bus Physical Addresses
User and Kernel Virtual Addresses
Memory Ordering: Big vs. Little Endian
32-bit vs. 64-bit Memory Addressing
Memory Allocation
Low-Level Allocation Mechanisms
The Mach Zone Allocator
The kalloc Family
Memory Allocation in BSD
I/O Kit Memory Allocation
Allocating Memory with the C++ New Operator
Memory Descriptors
The IOBufferMemoryDescriptor
Other Memory Descriptors
Mapping Memory
Mapping Memory from a User Space Task into Kernel Space
The IOMemoryMap Class
Mapping Memory from the Kernel to a User Space Task
Mapping Memory to a Specific User Space Task
Physical Address Mapping
Summary
Synchronization and Threading
Synchronization Primitives
Atomic Operations
Locking
Spin locks
Mutexes
Condition Variables
Read/Write Mutexes
Synchronizing Asynchronous Events: Work Loops
IOCommandGate
Timers
Releasing Work Loops
Kernel Threads
Summary
Universal Serial Bus
USB Architecture
USB Transfer Speeds
Host Controllers
The USB Protocol
Endpoints
USB Descriptors
USB Device Classes
I/O Kit USB Support
USB Device and Driver Handling
Loading USB Drivers
USB Prober
Driver Example: USB Mass Storage Device Driver
Driver Startup
Handling Device Removals
Enumerating Interfaces
Enumerating Endpoints
Performing Device Requests
Control Requests
Performing I/O to Bulk and Interrupt Endpoints
Dealing with Errors and Pipe Stalls
Isochronous I/O
Asynchronous Requests
Summary
PCI Express and Thunderbolt
PCI Express
Thunderbolt
ExpressCard
Configuration Space Registers
PCI in I/O Kit
Matching and Loading Drivers
Driver Example: A Simple PCI Driver
Accessing Configuration Space Registers
Accessing the Extended Configuration Space
Searching for Capabilities Registers
PCI I/O Memory Regions
Enumerating I/O Regions
Mapping and Accessing Device Memory Regions
Accessing I/O Space
Handling Device Removal
Interrupts
I/O Kit Interrupt Mechanisms
Registering to Receive Interrupts
Enabling Message Signaled Interrupts
Handling Primary Interrupts
Handling Secondary Interrupts
Direct Memory Access
Translating Physical Addresses to Bus Addresses
Preparing Memory for DMA
Building a Scatter/Gather List
The IODMACommand Class
Summary
Power Management
The I/O Registry Power Plane
Power Management in the I/O Kit
Responding to Power State Changes
Responding to Power State Changes
Requesting Power State Changes
Handling Device Idle
Observing Device Power State Changes
Putting It All Together
Summary
Serial Port Drivers
Mac OS X Serial Port Architecture Overview
Serial Port Drivers
Manually Instantiating a Driver Object
Implementing the IOSerialDriverSync Class
Serial Port State
Serial Port Events
Serial Data Transfer
Accessing a Serial Port from User Space
Summary
Audio Drivers
An Introduction to Digital Audio and Audio Devices
Core Audio
I/O Kit Audio Support
Implementing an Audio Driver
Driver and Hardware Initialization
Registering Audio Controls
Implementing an Audio Engine
I/O Engine Initialization
Creating and Initializing Audio Streams
Handling Format Changes
Clipping and Converting Samples
Starting and Stopping the Audio Engine
Engine Operation: Handling Interrupts and Timestamps
Additional Audio Engine Functionality
Summary
Networking
Network Memory Buffers
Working with Memory Buffers
Network Kernel Extensions
Kernel Control KPI
Socket Filters
Building an Application-Level Firewall Using Socket Filters
AppWall Operation and Data Structures
Attaching and Detaching the Filter
Handling Connections
Socket Data Input and Output
Internet Protocol Filters
Interface Filters
Debugging and Testing Network Extensions
Networking in the I/O Kit
Building a Simple Ethernet Controller Driver
The Design of MyEthernetDriver
Driver Initialization and Startup
Medium and Status Selection
Configuring the Device Hardware Address
Enabling and Disabling the Device
Transmitting Network Packets
Receiving Packets
Taking MyEthernetDriver for a Test-Drive
Summary
Storage Systems
Transport Layer Drivers
The IOBlockStorageDevice Interface
Building a RAM Disk Device
Partition Schemes
Implementing a Sample Partition Scheme
The Media Content Hint Property
Media Filter Drivers
A Sample Filter Scheme for Encryption
Creating a Custom GUID Partition Table
Summary
User-Space USB Drivers
Behind the Scenes
The IOUSBLib Framework
Handling Asynchronous Operations
The IOUSBDeviceInterface Class
The IOUSBInterfaceInterface Class
Property Methods
Endpoint Data Transfer Methods
Low-Latency Isochronous Transfers
Summary
Debugging
Common Types of Problems
Kernel Panics
Debugging Mechanisms
Recovering from Crashes During Boot
Tracing with IOLog()
Printing Stack Traces
Remote Tracing over FireWire
Remote Kernel Core Dumps
KDB
Remote Debugging with GDB over Ethernet or FireWire
Configuring the Host Machine
Attaching to the Remote Target
Debugging Using FireWire
Live Debugging of a Running Kernel
Debugging Using a Virtual Machine
Debugging in the Kernel Using GDB
Kernel GDB Macros
Creating Symbol Information for KEXTs
Debugging KEXTs with GDB
Understanding Kernel Panic Logs
x86-64 Calling Conventions
Diagnosing Hung Processes with Activity Monitor
Finding Memory and Resource Leaks
Advanced Kernel Programming
SSE and Floating Point in the Kernel
Multi-Function Drivers
Writing I/O Kit Families
Kernel Control KPI
Kernel Control Registration
Client Connections
Getting and Setting Options
Accessing Kernel Controls from User Space
Working with Processes in the Kernel
Loading Resources
Beyond KEXT Resources
Notifications from Kernel Drivers
427Summary
Deployment
Installing and Loading Kernel Extensions
Loading Preferences and Settings
Versioning Kernel Extensions
Testing and Quality Assurance
Packaging KEXTs and Software
Building a Package for the Hello World Kernel Extension
Adding Contents to the Package
Configuring the Package
Building the Package
Uninstalling Packages
Summary
Index
Numbers and Symbols
A
B
C
D
E
F
G
H
I, J
K
L
M
N
O
P, Q
R
S
T
U
V
W
X, Y
Z