Darwin & XNU: Inside the macOS Kernel
Date: 2025-11-24 Tags: macOS, Kernel, Mach, BSD, C Author: Wissam Ztaoui
Introduction
macOS is not Linux. It’s not purely Unix. It’s Darwin. At its heart beats the XNU kernel (X is Not Unix). XNU is a hybrid kernel, a Frankenstein monster stitching together the microkernel philosophy of Mach with the monolithic robustness of BSD.
1. The Hybrid Architecture
Mach (The Microkernel)
Mach handles the lowest-level primitives:
- Tasks & Threads: Scheduling.
- Virtual Memory: Memory management objects.
- IPC (Inter-Process Communication): The defining feature of Mach.
BSD (The Monolith)
Wrapped around Mach is the BSD layer (derived from FreeBSD). It provides:
- POSIX API:
fork(),exec(),open(),read(). - Network Stack: The TCP/IP stack.
- File Systems: APFS, HFS+.
- User/Group IDs: Permissions model.
Interaction: When you call fork() (BSD), XNU internally calls task_create() (Mach).
2. Mach Ports: The Nervous System
In Linux, “everything is a file”. In Mach, “everything is a port”. A port is a secure, kernel-managed communication channel.
- Rights: You don’t own a port; you hold “rights” to it (Send Right, Receive Right).
- Messages: Processes communicate by sending messages to ports.
Example:
When you launch an app, launchd gives it a set of bootstrap ports. If the app wants to talk to the Window Server, it looks up the service name, gets a send right to the Window Server’s port, and sends a message.
3. IOKit: Object-Oriented Drivers
Most kernels (Linux, Windows) write drivers in C. Apple created IOKit, a subset of C++ for writing drivers.
- Embedded C++: No exceptions, no RTTI, strict memory management.
- Object Graph: Drivers are organized in a tree (The IORegistry). You can view this with
ioreg -l.
Power Management: IOKit handles power states (sleep/wake) automatically through the object hierarchy.
4. The Boot Process
- BootROM: Hardware root of trust. Loads iBoot.
- iBoot: The second-stage loader. Verifies and loads the kernel cache.
- XNU Kernel: Initializes Mach, then BSD, then IOKit.
- launchd: The first user-mode process (PID 1). It replaces the traditional
initandsystemd. It manages daemons, agents, and XPC services.
5. Security: Kexts vs. System Extensions
Kernel Extensions (Kexts)
Traditionally, drivers ran in Ring 0 (.kext). A bug in a kext panicked the entire OS.
System Extensions (The Future)
Apple is deprecating Kexts. New extensions (Network, Endpoint Security) run in User Space.
- If a user-space driver crashes, it just restarts. The kernel stays alive.
- DriverKit: The new framework for writing user-space drivers using IOKit concepts.
Conclusion
Darwin is a fascinating study in OS history. It combines the academic purity of Mach’s IPC with the industrial strength of BSD, wrapped in a modern C++ driver framework. It is arguably the most complex mainstream kernel in existence.