XNU – Kernel Mac OS X

Questo articolo nasce da una mia recente rilettura della famosa diatriba Kernel Monolitico vs MicroKernel, tra il giovinastro Linus Torvalds ( Kernel Monolitico ) ed il professore rinomato  Andy Tanenbaum ( MicroKernel ). Vi rimando a questo link per avere una idea sul loro scambio di opinioni a riguardo

http://www.dina.dk/~abraham/Linus_vs_Tanenbaum.html

Da ormai tre anni ho scelto di usare Mac, in principo la scelta e’ stata dettata dalla necessita’ di liberare la mia scrivania da tutti quei fili penzolanti ( mia madre voleva uccidermi 😛 ) e dal fatto che iMac ha il suo fascino ( soprattutto da quando gira su IA64 ) e la sua eleganza. Con il passare del tempo sono rimasto ammaliato dalla bellezza e semplicita’ del Sistema Operativo di Cupertino, la potenza di un sistema BSD-based con un interfaccia accattivante e’ stata davvero una bella scoperta, fino ad arrivare a documentarmi sull’architettura alla base di tale sistema e cercare di capire qualcosa in piu’…

Architettura Kernel Mac OS X

Il cuore di Mac OS X e’ il kernel XNU, il quale puo’ essere visto come un insieme di piu’ componenti : il core basato su Mach 3, le features supplementari offerte da FreeBSD 5, la personalita’ di un Sistema Operativo basato su BSD ed un ambiente basato su un sistema object-oriented per quanto concerne i driver. In effetti il Kernel di Mac OS X e’ molto di piu’ che XNU, infatti esistono molti driver che non risiedono nel core di XNU ma derivano dai packages Darwin.

Per avere un idea delle estensione kernel che girano sul vostro sistema Mac OS X basta dare il seguente comando:


$ kextstat

oppure andare nella seguente cartella per vedere quali estensioni sono presenti


/System/Library/Extensions/

Un attimo pero’.. io ho sempre saputo che il cuore di Mac OS X fosse a MikroKernel.. ora questa teoria sembra vacillare 🙁

Xnu Is Not a Microkernel
All kernel components reside in a single kernel address space in Mac OS X. Although the kernel is
modular and extensible, it is still monolithic. Nevertheless, note that the kernel closely works with a
few user-space daemons such as dynamic_pager, kextd, and kuncd.

La citazione deriva direttamente dalla documentazione ufficiale Apple. Vedremo nei prossimi paragrafi cosa puo’ essere considerato a MicroKernel e cosa no.

Mach

Se il kernel XNU e’ il core di Mac OS X, Mach puo’ essere considerato il core di XNU.
Nato da un progetto di Rick Rashid e Avie Tevaniane’ alla Carnegie Mellon University con il preciso compito di essere un Sistema Operativo UNIX-based compatibile, e’ il responsabile dell’astrazione del sistema hardware, un metodo molto comune nei moderni Sistemi Operativi  che serve per disaccoppiare l’hardware sottostante con lo strato software.
Il cuore del Kernel Mach e’ a MicroKernel, tale kernel e’ orientato alla comunicazione tramite il meccanismo IPC ( Inter-Process Communication ) e con il pieno supporto al multiprocessing. Tale scelta implementativa e’ stata fatta per cercare di diminuire l’ammontare del codice che gira a livello kernel e permettere agli altri moduli del kernel ( FileSystem, Networking, User Interface ) di poter girare a livello user in modo da non creare problemi critici al sistema in caso di failure.
Nelle prima versioni di Mach basato sulle versione UNIX, il livello UNIX girava come server in un tash separato. Adesso, in Mac OS X, Mach e BSD girano nello stesso spazio di indirizzi.

Mach offre una intefaccia trasparente al livello applicativo per i servizi a basso livello, eccovi una lista degli aspetti di cui Mach e’ responsabile:

  • Astrazione hardware
  • Gestione del processore, incluso lo scheduling dei processi ed SMP
  • Multitasking preempitivo, incluso il supporto ai threads ed ai tasks
  • Gestione delle memoria virtuale, del paging, protezione della memoria
  • Meccanismi IPC di basso livello, che sono alla base dello scambio dei messaggi nel kernel
  • Supporto al real-time
  • Supporto al debugging del kernel

Mach e’ spesso considerato a MicroKernel, ma nelle versione precedenti al Mach 3 il suo sistema era prettamente monolitico. Anche se Apple usa una implementazione basata su Mach 3, XNU non usa Mach come un MicroKernel tradizionale a riprova di questo sia il la parte di BSD che quella di I/O girano allo stesso livello di Mach, e tutti condividono lo stesso spazio di indirizzi.

BSD

Il kernel di Mac OS X include molte linee di codice derivanti direttamente da FreeBSD ( circa un milione di linee di codice ). Come detto in precedenza, tale codice gira allo stesso livello di Mach. Il codice incorporato da FreeBSD, per poter funzionare correttamente con Mach ed il Kit I/O, e’ stato modificato in buona parte. Nonostante tali modifiche, alcune caratteristiche tipiche dei sistemi BSD sono rimaste intatte:

  • Il modello dei processi BSD-style
  • Segnali
  • user ID, permessi e le policy di sicurezza di base
  • APIs POSIX
  • API asincrone di I/O
  • System Call BSD-style
  • TCP/IP stack, BSD socket ed il firewall
  • Virtual File System (VFS) e numerosi file system indipendenti
  • System V
  • Framework Cryptographic
  • ACL (Access Control List)

Per avere un idea di quanto sia complicata la coesistenza tra lo stile BSD e quello Mach pensate al seguente esempio. Nei sistemi BSD unita’ fondamentale di esecuzione e’ il processo, mentre in Mach e’ il Thread. Tale disparita’ e’ stata superata associando ad ogni singolo processo di BSD un task Mach che consiste esattamente in un Thread. Quando e’ chiamata una System Call come fork(), il codice BSD presente nel kernel usa le chiamate a Mach per crere un task ed una struttura Thread.
Un altro esempio di questa disparita’ tra il sistema BSD e quello Mach e’ la gestione della sicurezza, in Mach viene gestito tramite i right port, mentre in BSD e’ usato il modello dei diritti di accesso sui processi. La disparita’ tra i due modelli e’ stata la causa di numerosi vulnerabilita’ di Mac OS X sulla escalation dei privilegi :P. Per tale motivo sono state inserite delle ulteriori traps tra lo strato Mach e le System Call effettuate dalle applicazioni a livello kernel.

I/O Kit

I/O Kit e’ l’open source, object-oriented, framework dei device driver responsabile della gestione e del caricamento dinamico dei device driver. Questi drivers vengono usati per il caricamento dinamico nel kernel dei moduli necessari per il corretto funzionamento dei differenti hardware.


unicondor@unicondor:~> kextstat
Index Refs Address    Size       Wired      Name (Version) <Linked Against>
1   74 0          0          0          com.apple.kpi.bsd (10.6.0)
2    4 0          0          0          com.apple.kpi.dsep (10.6.0)
3   98 0          0          0          com.apple.kpi.iokit (10.6.0)
4  105 0          0          0          com.apple.kpi.libkern (10.6.0)
5   90 0          0          0          com.apple.kpi.mach (10.6.0)
6   29 0          0          0          com.apple.kpi.private (10.6.0)
7   47 0          0          0          com.apple.kpi.unsupported (10.6.0)
8    0 0          0          0          com.apple.kernel.6.0 (7.9.9)
9    0 0          0          0          com.apple.kernel.bsd (7.9.9)
10    0 0          0          0          com.apple.kernel.iokit (7.9.9)
11    0 0          0          0          com.apple.kernel.libkern (7.9.9)
12    1 0          0          0          com.apple.kernel.mach (7.9.9)
13   13 0x913000   0x4000     0x3000     com.apple.iokit.IOACPIFamily (1.3.0) <7 6 4 3>
14   23 0x927000   0x11000    0x10000    com.apple.iokit.IOPCIFamily (2.6) <7 5 4 3>
15    2 0x10ed000  0x42000    0x41000    com.apple.driver.AppleACPIPlatform (1.3.5) <14 13 7 6 5 4 3>
16    0 0x1364000  0x1e000    0x1d000    com.apple.driver.AppleIntelCPUPowerManagement (105.13.0) <7 6 5 4 3 1>
17    8 0x1166000  0x18000    0x17000    com.apple.iokit.IOStorageFamily (1.6.2) <7 6 5 4 3 1>
18    0 0x14e5000  0x11000    0x10000    com.apple.driver.DiskImages (289) <17 7 6 5 4 3 1>
19    0 0x15ee000  0x8000     0x7000     com.apple.nke.applicationfirewall (2.1.11) <7 6 5 4 3 1>
20    0 0x1a22000  0x3000     0x2000     com.apple.security.TMSafetyNet (6) <7 6 5 4 2 1>
21    2 0x1a25000  0x3000     0x2000     com.apple.kext.AppleMatch (1.0.0d1) <4 1>
22    0 0x1a28000  0x5000     0x4000     com.apple.security.quarantine (0) <21 7 6 5 4 2 1>

Come potete vedere, molte delle entita’ della lista sono caricate all’indirizzo zero. Questo significa che sono parte del Kernel e non sono dei veri e propri device driver ( Ex. non possono essere unloaded). Il primo device driver nel mio caso e’ il 13.

Supponiamo di voler trovare e caricare il modulo kernel responsabile del File System MS-DOS:


$ kextfind -bundle-id -substring ‘msdos’
/System/Library/Extensions/msdosfs.kext

Ora che sappiamo il suo nome, possiamo caricare il modulo in Mac OS X


$ sudo kextload /System/Library/Extensions/msdosfs.kext
kextload: /System/Library/Extensions/msdosfs.kext loaded successfully

Per controllare che sia stato caricato con successo:


$ kextstat | grep msdos
126 0 0x346d5000 0xc000 0xb000
com.apple.filesystems.msdosfs (1.5.2) <7 6 5 2>

Il quale ci dice che e’ il driver numero 126 ad essere stato caricato, ci sono zero referenze al driver ( nessuno lo sta usando ) , ed e’ stato caricato all’indirizzo 0x346d5000 ed ha una grandezza 0xc000 e che uccupa in memoria kernel bytesl.

Infine possiamo fare unload del driver digitando:


$ sudo kextunload com.apple.filesystems.msdosfs
kextunload: unload kext /System/Library/Extensions/msdosfs.kext
succeeded

Spero di non avermi annoiato troppo… anche se il semplice fatto di essere arrivati fin qui, come me, dimostra che amate queste tipo di letture 😀

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.