Quien administra servidores Linux y estaciones macOS encuentra muchas herramientas conocidas al abrir Terminal: procesos, señales, sockets, permisos, descriptores de archivos y llamadas POSIX. Sin embargo, debajo de esa interfaz Unix, macOS utiliza XNU, un kernel híbrido que combina subsistemas procedentes de Mach y BSD, además de IOKit para buena parte de la infraestructura relacionada con controladores. No son dos kernels ejecutándose simultáneamente, sino componentes integrados dentro de un mismo kernel y espacio de direcciones.
Las claves de XNU para desarrolladores en 20 segundos
- XNU es el kernel utilizado por Darwin y, sobre él, por macOS.
- Combina el kernel Mach con componentes procedentes de BSD e IOKit.
- Mach aporta tareas, hilos, memoria virtual e IPC mediante puertos y mensajes.
- BSD proporciona buena parte de las interfaces Unix que utilizan las aplicaciones.
- Conocer ambas capas ayuda al depurar IPC, rendimiento, procesos y problemas de bajo nivel.
Para el desarrollo habitual esta arquitectura puede permanecer invisible. Una aplicación llama a read(), abre un socket o crea procesos utilizando interfaces familiares. Cuando el diagnóstico baja hacia XPC, Mach ports, memoria virtual, planificación o un kernel panic, empiezan a aparecer conceptos bastante diferentes de los encontrados habitualmente en Linux.
Apple mantiene además el código de XNU abierto. Su repositorio permite comprobar físicamente esa separación: osfmk contiene los subsistemas basados en Mach, mientras bsd contiene los subsistemas BSD. También aparecen libsyscall, IOKit, componentes de seguridad y código específico de cada plataforma.
XNU no son dos kernels: Mach y BSD están integrados
El nombre XNU significa X is Not Unix. Apple lo define actualmente como un kernel híbrido que combina Mach, desarrollado originalmente en Carnegie Mellon University, con componentes procedentes de FreeBSD y una API C++ para controladores denominada IOKit.
La distinción entre Mach y BSD sigue siendo importante porque cada parte aporta abstracciones diferentes.
Mach utiliza conceptos como tasks, threads, ports y messages.
Una task representa un entorno de ejecución que incluye su espacio de direcciones y recursos asociados. Los threads son las unidades que realmente ejecutan código dentro de ese contexto.
La comunicación entre componentes puede utilizar Mach IPC (Inter-Process Communication), basada en puertos y mensajes.
Esta arquitectura continúa siendo visible en interfaces actuales de macOS. Los desarrolladores probablemente conozcan más XPC, una abstracción de alto nivel empleada para comunicación entre procesos y servicios, pero por debajo existen mecanismos profundamente relacionados con la arquitectura IPC de Darwin.
BSD aporta la parte que resulta mucho más reconocible para un administrador Unix.
Aquí aparecen buena parte del modelo de procesos POSIX, señales, sockets, sistema de archivos virtual y las llamadas al sistema utilizadas habitualmente por aplicaciones.
Por eso código como este resulta completamente normal en macOS:
int fd = open("/etc/hosts", O_RDONLY);
read(fd, buffer, sizeof(buffer));
close(fd);Lenguaje del código: JavaScript (javascript)
El programa trabaja con interfaces Unix conocidas.
Sin embargo, sería incorrecto imaginar que read() entra en un kernel BSD independiente y posteriormente envía obligatoriamente un mensaje a otro kernel Mach.
BSD y Mach forman parte de XNU y comparten el espacio de direcciones del kernel.
Esta decisión diferencia XNU de un diseño de microkernel puro, donde determinados servicios podrían ejecutarse como procesos independientes en espacio de usuario y comunicarse mediante IPC.
Integrarlos evita parte del coste que supondría cruzar continuamente esas fronteras.
Desde la perspectiva de operaciones, una forma sencilla de entenderlo es pensar en XNU como un kernel con diferentes familias de subsistemas e interfaces, no como dos sistemas operativos ejecutándose uno encima del otro.
Lo que cambia al depurar macOS después de trabajar con Linux
Las diferencias se vuelven especialmente visibles al diagnosticar problemas.
En Linux, herramientas como strace permiten observar llamadas al sistema:
strace cat /etc/hosts
En macOS, históricamente una alternativa habitual ha sido dtruss, construida sobre DTrace:
sudo dtruss cat /etc/hosts
Una salida simplificada puede mostrar operaciones reconocibles:
open(...)
fstat64(...)
read(...)
close(...)
Hasta aquí la experiencia resulta bastante familiar para cualquier administrador Unix.
El problema aparece cuando la actividad investigada no está únicamente en esa superficie POSIX.
XNU dispone también de Mach traps, que exponen operaciones relacionadas con la infraestructura Mach. El propio código fuente mantiene estas interfaces dentro de osfmk, separado de los subsistemas BSD.
Eso ayuda a explicar por qué determinadas trazas de macOS muestran referencias como:
mach_msg
mach_msg2
task
thread
semaphore
en lugar de limitarse a nombres asociados a syscalls Unix.
No significa necesariamente que exista un problema.
El administrador simplemente ha atravesado la abstracción POSIX y está observando componentes internos de XNU.
Esta diferencia resulta particularmente útil al trabajar con XPC, extensiones, procesos aislados mediante sandbox, herramientas de profiling o problemas de comunicación entre servicios.
También hay que tener cuidado con tutoriales antiguos que proponen comandos DTrace específicos. Las restricciones de seguridad introducidas en sucesivas generaciones de macOS hacen que no todas las técnicas históricas de tracing puedan utilizarse actualmente en cualquier Mac sin modificaciones.
Para análisis de rendimiento de aplicaciones, Apple dirige buena parte de esta actividad hacia Instruments y las herramientas integradas con Xcode. Para debugging del propio kernel, el repositorio de XNU documenta incluso el uso de LLDB sobre kernels preparados para desarrollo.
Mirar el código de XNU ayuda a entender la arquitectura
Una ventaja para desarrolladores y administradores interesados en internals es que Apple publica una parte considerable del código fuente de XNU.
La estructura del repositorio resulta bastante descriptiva.
osfmk contiene los subsistemas basados en Mach.
bsd contiene los subsistemas BSD.
libsyscall proporciona la interfaz de biblioteca de llamadas al sistema para programas en espacio de usuario.
libkern contiene código relacionado con la biblioteca C++ de IOKit.
security reúne interfaces e implementaciones relacionadas con políticas Mandatory Access Control (MAC).
pexpert incluye código específico de plataforma, como determinadas funciones relacionadas con interrupciones y operaciones atómicas.
Esta organización permite seguir una operación desde la interfaz expuesta al espacio de usuario hacia diferentes subsistemas internos sin depender únicamente de diagramas históricos.
También muestra por qué reducir XNU a «BSD ejecutándose encima de Mach» puede resultar útil como introducción, pero no describe correctamente toda su implementación.
Los componentes están mucho más integrados.
Esa integración tiene consecuencias prácticas en la gestión de procesos.
Desde la perspectiva BSD puede hablarse de un proceso Unix. Desde la perspectiva Mach aparecen conceptos como task y threads. Ambas representaciones forman parte de la misma ejecución y XNU mantiene las relaciones necesarias entre ellas.
Lo mismo sucede con memoria.
Una aplicación Unix puede trabajar normalmente con mmap() sin conocer la arquitectura interna del kernel, mientras XNU utiliza internamente el subsistema de memoria virtual derivado de Mach.
El objetivo es precisamente que un desarrollador de aplicaciones no necesite conocer estos detalles.
Pero cuando se investiga un problema de bajo nivel, comprenderlos evita interpretar incorrectamente lo que muestran las herramientas.
Cuándo necesita un sysadmin conocer Mach
Para la administración cotidiana de un Mac probablemente nunca sea necesario trabajar directamente con Mach IPC.
Comandos como:
ps
top
lsof
netstat
vm_stat
fs_usage
launchctl
permiten diagnosticar una gran cantidad de problemas sin bajar hasta ese nivel.
Sin embargo, conocer la arquitectura de XNU empieza a resultar útil cuando el problema afecta a comunicación entre procesos, consumo de memoria, comportamiento de hilos, servicios gestionados mediante launchd, sandboxing o componentes específicos de macOS.
También ayuda al leer documentación técnica.
Un Mach port no debe interpretarse como un puerto TCP o UDP. Es un objeto del sistema IPC que permite enviar mensajes entre componentes.
Una Mach task tampoco equivale exactamente al concepto Unix de proceso, aunque exista una relación estrecha entre ambos dentro de macOS.
Un Mach thread representa una unidad de ejecución administrada por el kernel.
Estas diferencias explican por qué herramientas y documentación de Apple pueden utilizar vocabulario que resulta extraño incluso para alguien con años administrando Linux o BSD.
Hay otro caso especialmente útil: los kernel panics.
Cuando una traza combina nombres relacionados con Mach, BSD, memoria virtual, IOKit o drivers, no está mostrando necesariamente varias capas independientes que hayan fallado una detrás de otra. Está recorriendo diferentes subsistemas del mismo XNU.
Para desarrolladores que trabajan exclusivamente sobre frameworks de alto nivel, esta distinción seguirá teniendo poca importancia.
Para quien desarrolla herramientas de sistema, extensiones, software de seguridad, virtualización o aplicaciones con una utilización intensiva de IPC, la arquitectura deja de ser un detalle histórico.
También resulta útil para evitar una simplificación bastante extendida: macOS no ejecuta dos kernels a la vez.
Ejecuta XNU.
La particularidad está en que ese único kernel conserva dos herencias muy visibles. BSD proporciona buena parte del mundo Unix que encuentra un desarrollador al abrir Terminal, mientras Mach continúa presente en abstracciones esenciales relacionadas con ejecución, memoria e IPC.
Después de años utilizando únicamente las interfaces POSIX puede parecer que Mach ha desaparecido. Basta bajar un nivel en una traza, revisar un kernel panic o abrir el código de osfmk para comprobar que sigue formando parte de la arquitectura diaria de cualquier Mac.
Preguntas frecuentes
¿macOS utiliza el kernel de FreeBSD?
No. macOS utiliza XNU, un kernel propio de Apple que combina el kernel Mach con componentes procedentes de BSD y otros subsistemas como IOKit.
¿XNU es un microkernel?
Se considera un kernel híbrido. Conserva conceptos y mecanismos procedentes de Mach, pero integra Mach y BSD dentro del espacio del kernel en lugar de mantener una arquitectura de microkernel pura con los servicios BSD separados.
¿Qué diferencia hay entre un proceso Unix y una Mach task?
El proceso pertenece a la visión BSD/POSIX que utilizan normalmente las aplicaciones. Mach utiliza el concepto de task para representar, entre otros elementos, el espacio de direcciones y recursos sobre los que ejecutan sus threads; XNU integra ambos modelos.
¿Por qué un administrador de sistemas debería conocer Mach?
No es necesario para las tareas habituales, pero resulta útil al diagnosticar IPC, XPC, problemas de memoria o hilos, software de bajo nivel y kernel panics donde aparecen simultáneamente componentes Mach y BSD.







