Análisis en profundidad de Darwin OS y el kernel XNU de Apple
(tansanrao.com)- El sistema operativo Darwin de Apple es el núcleo de tipo Unix que sirve de base para los sistemas operativos modernos de Apple, como macOS e iOS.
- Su pieza central es el kernel XNU, un kernel híbrido cuyo nombre significa "X is Not Unix".
- Combina la estructura del microkernel Mach con elementos de BSD Unix para equilibrar rendimiento y modularidad.
- Este artículo explica la evolución estructural de Darwin y XNU, desde las raíces de Mach y BSD hasta su evolución más reciente en Apple Silicon.
- Analiza los componentes clave del kernel (IPC, planificación, gestión de memoria, virtualización, etc.) y cómo se han adaptado al hardware moderno.
Origen del microkernel Mach (1985–1996)
- Mach comenzó en 1985 en Carnegie Mellon University, impulsado por Richard Rashid y Avie Tevanian.
- Fue diseñado como un microkernel que ofrecía solo las funciones esenciales para reducir la complejidad del kernel UNIX.
- Solo proporcionaba funciones de bajo nivel, como gestión de memoria, planificación basada en hilos e IPC basado en mensajes, mientras que el sistema de archivos, la red y otros componentes se separaban en servidores de espacio de usuario.
- Mach 2.5 se ejecutaba en espacio de kernel junto con parte del código del kernel BSD para compensar el rendimiento.
- Mach 3.0 hizo la transición hacia un verdadero microkernel y también influyó en la gestión de memoria de BSD.
- Mach introdujo los conceptos de Task y Thread, e implementó un modelo eficiente de memoria virtual.
- NeXT (fundada por Steve Jobs en 1985) desarrolló NeXTSTEP OS sobre la base de Mach 2.5 + 4.3BSD.
- El kernel de NeXTSTEP combinaba Mach y BSD en espacio de kernel, formando una estructura híbrida.
- Los drivers se desarrollaban con DriverKit basado en Objective-C, intentando un enfoque orientado a objetos.
- Apple adquirió NeXT en 1996 y con ello incorporó NeXTSTEP y el kernel XNU basado en Mach/BSD.
- Las primeras versiones de Mac OS X (Rhapsody) se desarrollaron sobre la estructura de kernel de NeXT.
Evolución inicial de Mac OS X (1997–2005)
- Apple integró en XNU código de Mach 3.0 basado en OSFMK 7.3 y actualizó la capa BSD con código de FreeBSD y 4.4BSD.
- Para mejorar el rendimiento y ampliar el soporte de hardware, mantuvo una estructura híbrida con funciones de BSD y Mach incorporadas.
- Se introdujo el nuevo framework de drivers I/O Kit: basado en C++ en lugar de Objective-C, optimizado para rendimiento y con soporte para hot-plugging.
- Resumen de características principales por versión:
- 10.1 Puma (2001): soporte para hilos en tiempo real, mejoras de rendimiento.
- 10.2 Jaguar (2002): introducción de IPv6, IPSec, Bonjour y journaling en HFS+.
- 10.3 Panther (2003): mejoras del kernel basadas en FreeBSD 5, incorporación de fine-grained locking para soporte multicore.
- XNU ofrecía soporte nativo para PowerPC, pero también mantenía código para x86 en preparación para la transición futura.
- 10.4 Tiger (2005): obtuvo certificación UNIX 03, sentó las bases para la transición a Intel e introdujo el sistema de eventos kqueue/kevent.
Era de 64 bits, multicore y iPhone OS (2005–2010)
- 10.5 Leopard (2007):
- soporte para x86_64 y posibilidad de drivers de 64 bits
- refuerzo de funciones de seguridad y depuración como ASLR, sandbox y DTrace
- último soporte oficial para PowerPC
- iPhone OS 1 (2007):
- basado en Darwin 9, con XNU portado a ARM
- introducción del mecanismo Jetsam para manejar falta de memoria
- sandbox obligatorio para todas las apps y exigencia de firma de código
- 10.6 Snow Leopard (2009):
- exclusivo para Intel, con soporte completo para kernel de 64 bits
- introducción de Grand Central Dispatch: framework de paralelización de tareas en espacio de usuario que coopera con el kernel
- integración de OpenCL y soporte para cómputo en GPU
- iOS 4 (2010):
- introducción de multitarea y planificación basada en prioridades (distinción entre background y foreground)
Modernización de macOS e iOS (2011–2020)
- 10.8~10.9 (2012–2013):
- introducción de Compressed Memory para optimizar el uso de RAM
- Timer Coalescing para mejorar el ahorro de energía de CPU
- evolución de la planificación orientada a eficiencia energética con App Nap, QoS y más
- 10.10~10.11 (2014–2015):
- introducción de SIP(System Integrity Protection): ni siquiera root puede modificar archivos del sistema
- se aseguró la capacidad de expandir XNU a múltiples dispositivos como watchOS y tvOS
- soporte para ARM64 e inicio de la preparación para abandonar ARM de 32 bits
- 10.12~10.14 (2016–2018):
- transición del sistema de archivos a APFS(Apple File System)
- soporte para snapshots, cloning y cifrado
- refuerzo de la seguridad de kext: aprobación del usuario obligatoria y validación más estricta de firma de código
- 10.15 Catalina (2019):
- introducción de DriverKit: ejecución de drivers en espacio de usuario (regreso a la filosofía del microkernel)
- mayor seguridad al separar el volumen del sistema como solo lectura
Era de Apple Silicon (2020–actualidad)
-
macOS 11 Big Sur (2020):
- soporte para Apple Silicon(M1) basado en ARM64
- soporte para planificación de CPU big.LITTLE: asignación de núcleos de eficiencia o rendimiento basada en QoS
- la estructura Mach VM se adapta bien a la arquitectura de memoria unificada
-
Refuerzo de seguridad y virtualización:
- soporte para funciones de seguridad por hardware de ARM como PAC(pointer authentication) y MTE(memory tagging)
- introducción de un nuevo framework de virtualización basado en las capacidades de hipervisor de Apple Silicon
- posibilidad de ejecutar VM ligeras para desarrolladores en macOS (control desde espacio de usuario)
-
Estructura de plataforma unificada:
- XNU se usa como kernel de todas las plataformas de Apple, incluyendo macOS, iOS, watchOS, tvOS, bridgeOS y visionOS
- gracias a la abstracción de plataforma de Mach, puede adaptarse con facilidad a distintas arquitecturas de CPU
Resumen de la cronología principal de XNU
- 1989 - NeXTSTEP 1.0 - introducción del híbrido XNU de Mach 2.5 + BSD
- 1996 - Apple adquiere NeXT - inicio del desarrollo de Rhapsody basado en Mach 3.0 + FreeBSD
- 2001 - Mac OS X 10.0 - consolidación de la estructura del kernel XNU y mejoras iniciales de rendimiento
- 2005 - 10.4 Tiger - certificación UNIX, preparación para la transición a Intel
- 2007 - 10.5 Leopard - soporte de 64 bits, refuerzo de seguridad, aparición de iPhone OS
- 2009 - 10.6 Snow Leopard - transición completa a Intel e introducción de GCD
- 2011 - 10.7 Lion - imposición del kernel de 64 bits, expansión del sandboxing
- 2013 - 10.9 Mavericks - introducción de compresión de memoria y planificación QoS
- 2015 - 10.11 El Capitan - introducción de SIP, expansión a dispositivos como watchOS
- 2017 - 10.13 High Sierra - APFS como predeterminado, refuerzo de seguridad de Kext
- 2019 - 10.15 Catalina - drivers ejecutándose en espacio de usuario con DriverKit
- 2020 - 11 Big Sur - soporte para Apple Silicon, introducción de una nueva estructura de virtualización
- 2022 - 13 Ventura - mejoras en la planificación para núcleos de alto rendimiento como los de M1 Max
- 2024 - 14 Sonoma - optimización para M2/M3 y soporte para Memory Tagging
Estructura y diseño del kernel XNU
Diseño de kernel híbrido: integración de Mach + BSD
- XNU tiene una estructura de kernel híbrido que reúne características tanto del microkernel (Mach) como del kernel monolítico (BSD).
- Mach abstrae y modulariza funciones de bajo nivel (hilos, memoria, IPC, etc.), mientras que BSD ejecuta directamente en espacio de kernel todo el conjunto de llamadas al sistema y APIs de UNIX.
- BSD y Mach están enlazados en un único binario de kernel y se ejecutan dentro del mismo espacio de direcciones.
- Dentro del kernel, las funciones de Mach y BSD se invocan directamente sin mensajes, y las llamadas al sistema UNIX se procesan con rendimiento comparable al de otros kernels Unix.
- Ejemplo: al llamar a
read(), el código del sistema de archivos BSD se ejecuta directamente en el kernel.
Rol de Mach
- Proporciona la infraestructura central del kernel: hilos, gestión de tasks, cambio de contexto, colas de planificación, timers y más.
- Proporciona IPC basado en mensajes mediante puertos Mach (con soporte para memoria compartida entre procesos y transferencia de buffers grandes).
- Implementa funciones avanzadas de gestión de memoria virtual, como memory objects, optimización copy-on-write y abstracción de espacio de direcciones.
Rol de BSD
- Proporciona funciones UNIX como procesos y PID, señales, ID de usuario, API POSIX, sistema de archivos, stack de red e IPC UNIX.
- Deriva de código BSD basado en FreeBSD, e incluye también funciones de OpenBSD/NetBSD.
- Implementa políticas de seguridad como framework de seguridad (KAuth, MAC), sandbox, SIP y validación de firma de código.
- Implementación de llamadas al sistema:
fork()realiza, por ejemplo, duplicación de VM en Mach y duplicación de descriptores de archivo en BSD. - Se encarga de la mayoría de las funciones UNIX, como VFS, red, manejo de signal y hilos POSIX.
I/O Kit
- Framework orientado a objetos para drivers que se ejecuta en espacio de kernel (usa un Embedded Subset de C++).
- Define la jerarquía de dispositivos y cada driver la implementa por herencia.
- Ofrece una interfaz user client accesible desde espacio de usuario.
- La sincronización del kernel y el control de hilos usan funciones de Mach, mientras que los drivers de sistema de archivos y red se conectan con BSD.
- Los drivers pueden cargarse dinámicamente como Kext y se cargan en memoria del kernel en formato Mach-O.
Mach IPC y paso de mensajes
- Los puertos Mach son el principal mecanismo de IPC entre kernel y espacio de usuario, o entre procesos de usuario.
- Cada proceso puede controlarse a través de puertos Mach, y daemons del sistema como launchd controlan procesos mediante esos puertos.
- Funciones avanzadas de macOS como Grand Central Dispatch y XPC están implementadas sobre mensajes Mach.
- Los mensajes Mach son seguros gracias a un sistema de permisos por puerto, y permiten transferencia de puertos y de memoria compartida.
- MIG(Mach Interface Generator) se utiliza para generar automáticamente código RPC basado en mensajes entre kernel y usuario.
- DriverKit implementa la comunicación entre el kernel y los drivers de espacio de usuario sobre la base de Mach IPC.
Scheduler y gestión de hilos
- Evolucionó desde un scheduler round-robin basado en prioridades sobre Mach.
- Cada CPU tiene su propia Run Queue, y los hilos se planifican según prioridad.
- Tras la llegada de iOS, se introdujeron políticas de planificación según el rol de la app (background/foreground).
- Planificación basada en clases QoS(Quality of Service): la prioridad se ajusta según el tipo de trabajo, como interacción del usuario o background.
- En Apple Silicon, los hilos se asignan a núcleos de eficiencia o de alto rendimiento según QoS.
- Los hilos en tiempo real (por ejemplo, audio) se ejecutan con prioridad a través de colas en tiempo real, y desde macOS 10.4 existe soporte para planificación por deadline.
- Cooperación con gestión de energía: optimización del rendimiento móvil mediante hilos idle, agrupación de timers y entrada en estados de ahorro de energía.
Gestión de memoria y memoria virtual
- Mach VM es el núcleo del sistema de memoria de XNU y tiene un diseño potente y flexible.
- El espacio de direcciones virtuales se basa en copy-on-write, lo que permite duplicación eficiente de memoria en
fork(). - Estructura de memory object y pager:
- el daemon de espacio de usuario
dynamic_pageradministra el área de swap - el mapeo de archivos se procesa dentro del kernel a través del vnode pager
- el daemon de espacio de usuario
- Desde Mavericks se introdujo memoria comprimida: cuando falta memoria, las páginas se comprimen y conservan en lugar de intercambiarse al disco.
- pmap: capa dependiente de la máquina que administra la memoria física y las tablas de páginas de cada arquitectura.
- El kernel tiene su propio espacio de direcciones y algunas áreas se configuran como memoria fija (wired).
- macOS refuerza la seguridad de memoria mediante guard pages para depuración, asignación zero-fill y protección por regiones.
- Mach VM maneja eficientemente el uso compartido de frameworks, entre otras cosas, mediante memoria compartida y ajustes de Inheritance.
- En Apple Silicon, la GPU y la memoria comparten un espacio unificado, por lo que Mach VM optimiza la asignación según las características de la memoria.
Soporte de virtualización
- XNU no tenía funciones de hipervisor al principio, pero desde OS X 10.10 comenzó a ofrecer soporte de virtualización a través de Hypervisor.framework.
- En sistemas basados en Intel, eso permitió ejecutar VM en espacio de usuario usando VT-x.
- En Apple Silicon basado en ARM, se aprovechan las capacidades de virtualización EL2 mediante Virtualization.framework.
- El hipervisor interno del kernel se encarga de memoria virtual, manejo de traps de vCPU, planificación y más.
- Aprovecha la estructura de hilos y tasks de Mach en XNU para manejar vCPU como hilos del host.
- macOS también ofrece funciones de emulación x86 como Rosetta 2, junto con traducción de syscalls y compatibilidad ABI.
- Desde iOS 15, también se permite virtualización de forma limitada en iOS (requiere modo de desarrollador).
Estructura de cómputo seguro
- Secure Enclave:
- subsistema de seguridad independiente integrado en los SoC de Apple
- ejecuta un microkernel separado llamado sepOS, que protege datos biométricos, claves criptográficas y más
- mantiene el procesamiento de seguridad aislado incluso si el kernel principal se ve comprometido
- Exclaves:
- nueva zona de aislamiento introducida desde macOS 14.4 e iOS 17
- separa recursos sensibles, como autenticación de Apple ID, buffers de audio y datos de sensores, fuera del kernel principal
- se controla mediante Kext y frameworks dedicados, como
ExclaveKextClient.kext - incluso si el kernel se ve comprometido, el área exclave permanece protegida de forma independiente
- enclave refleja la idea de un área incluida dentro del sistema, mientras que exclave representa un área separada conectada externamente al sistema.
Conclusión
- XNU es un kernel con una estructura híbrida práctica que equilibra las ventajas del microkernel y del kernel monolítico.
- La capa de abstracción de Mach hace posible la transición entre distintas arquitecturas de CPU y la expansión del sistema, mientras que BSD ofrece compatibilidad POSIX y un entorno Unix estable.
- Apple separa funciones hacia espacio de usuario cuando es necesario mediante Mach IPC, y mantiene conexión directa dentro del kernel para maximizar la eficiencia.
- Con una arquitectura multicapa que incluye drivers (DriverKit en espacio de usuario), virtualización (Hypervisor.framework), scheduler (QoS) y gestión de memoria (Compressed Memory), responde con flexibilidad a las exigencias de los sistemas modernos.
- Darwin y XNU partieron de NeXTSTEP y evolucionaron hasta convertirse en el núcleo de cientos de millones de dispositivos Apple, y siguen evolucionando.
Aún no hay comentarios.