
Noyau hybride combinant Mach, FreeBSD et IOKit pour macOS et iOS. Fournit les services de base du système d'exploitation, un framework de pilotes et l'application des politiques de sécurité sur x86_64 et ARM64.
Le noyau XNU fait partie du système d'exploitation Darwin utilisé dans les systèmes d'exploitation macOS et iOS. XNU est un acronyme pour X is Not Unix. XNU est un noyau hybride combinant le noyau Mach développé à l'Université Carnegie Mellon avec des composants de FreeBSD et une API C++ pour l'écriture de pilotes appelée IOKit. XNU fonctionne sur x86_64 et ARM64 pour les configurations à un seul processeur et multi-processeur.
config - configurations pour les API exportées pour l'architecture et la plateforme supportéesSETUP - Ensemble de base d'outils utilisés pour configurer le noyau, la gestion des versions et des symboles kext.EXTERNAL_HEADERS - En-têtes provenant d'autres projets pour éviter les cycles de dépendances lors de la construction. Ces en-têtes doivent être régulièrement synchronisés lorsque la source est mise à jour.libkern - Code de la bibliothèque C++ IOKit pour la gestion des pilotes et des kexts.libsa - Code d'amorçage du noyau pour le démarragelibsyscall - Interface de la bibliothèque d'appels système pour les programmes de l'espace utilisateurlibkdd - Source de la bibliothèque utilisateur pour l'analyse des données du noyau comme les données fragmentées du noyau.makedefs - Règles et définitions de haut niveau pour la construction du noyau.osfmk - Sous-systèmes basés sur le noyau Machpexpert - Code spécifique à la plateforme comme la gestion des interruptions, les atomiques, etc.security - Interfaces de politique de contrôle d'accès obligatoire et implémentation associée.bsd - Code des sous-systèmes BSDtools - Un ensemble d'utilitaires pour tester, déboguer et profiler le noyau.DEVELOPMENTLe système de construction xnu peut construire un noyau en se basant sur les variables KERNEL_CONFIGS et ARCH_CONFIGS comme arguments.
Voici la syntaxe :```text
make SDKROOT= ARCH_CONFIGS= KERNEL_CONFIGS=
Où :
* `<sdkroot>` : chemin vers le SDK macOS sur le disque. (par défaut `/`)
* `<variant>` : peut être `debug`, `development`, `release`, `profile` et configure les indicateurs de compilation et les assertions dans tout le code du noyau.
* `<arch>` : peut être une architecture valide pour laquelle construire. (Par ex. `X86_64`)
Pour construire un noyau pour la même architecture que le système d'exploitation en cours, tapez simplement```text
make SDKROOT=macosx.internal
De plus, il est possible de configurer les architectures via ARCH_CONFIGS et les configurations du noyau avec KERNEL_CONFIGS.```text
make SDKROOT=macosx.internal ARCH_CONFIGS=X86_64 KERNEL_CONFIGS=DEVELOPMENT
make SDKROOT=macosx.internal ARCH_CONFIGS=X86_64 KERNEL_CONFIGS="RELEASE DEVELOPMENT DEBUG"
> Remarque : Par défaut, l'architecture est définie sur celle de la machine de compilation, et la configuration par défaut du noyau est définie pour compiler pour `DEVELOPMENT`.
Cela créera également une image amorçable, kernel.[config], et un binaire du noyau avec les symboles, kernel.[config].unstripped.
Pour installer le noyau dans un DSTROOT, utilisez la cible `install_kernels` :```text
make install_kernels DSTROOT=/tmp/xnu-dst
Pour une expérience de débogage du noyau plus satisfaisante, avec accès à toutes les variables locales et arguments, mais sans toutes les vérifications supplémentaires du noyau DEBUG, ajoutez quelque chose comme ce qui suit à votre commande make :```text CFLAGS_DEVELOPMENTARM64="-O0 -g -DKERNEL_STACK_MULTIPLIER=2" CXXFLAGS_DEVELOPMENTARM64="-O0 -g -DKERNEL_STACK_MULTIPLIER=2"
N'oubliez pas de remplacer `DEVELOPMENT` et `ARM64` par la version et la plateforme appropriées.
> Drapeaux supplémentaires : Vous pouvez passer des drapeaux supplémentaires au compilateur C en ligne de commande avec le paramètre de construction `EXTRA_CFLAGS`. Ces drapeaux sont ajoutés aux `CFLAGS` de base, et la valeur par défaut du paramètre est une chaîne vide.
>
> Ce paramètre vous permet par exemple d'activer sélectivement du code de débogage protégé par une macro de préprocesseur. Exemple d'utilisation...
>
> ```text
> make SDKROOT=macosx.internal PRODUCT_CONFIGS=j314s
> EXTRA_CFLAGS='-DKERNEL_STACK_MULTIPLIER=2'
> ```
* Pour construire avec la configuration du noyau RELEASE
```text
make KERNEL_CONFIGS=RELEASE SDKROOT=/path/to/SDK
```
### Construction du binaire du noyau FAT
Définissez les architectures dans votre environnement ou lors de l'exécution d'une commande make.```text
make ARCH_CONFIGS="X86_64" exporthdrs all
Le système de build XNU peut éventuellement afficher une sortie de build formatée en couleur. Pour activer cela, vous pouvez soit
définir la variable d'environnement XNU_LOGCOLORS à y, soit passer LOGCOLORS=y à la commande make.
La version xnu est dérivée du SDK ou KDK en lisant le CFBundleVersion
de leur fichier System/Library/Extensions/System.kext/Info.plist.
Cela peut être personnalisé en définissant la variable RC_DARWIN_KERNEL_VERSION dans
l'environnement ou sur la ligne de commande make.
Voir doc/building/xnu_version.md pour plus de détails.
Par défaut, un référentiel d'informations de débogage DWARF est créé lors de la phase d'installation ; il s'agit d'un « bundle » nommé kernel.development.<variant>.dSYM Pour sélectionner l'ancien format d'information de débogage STABS (où les informations de débogage sont intégrées dans l'image kernel.development.unstripped), définissez la variable d'environnement BUILD_STABS.```sh export BUILD_STABS=1 make
## Construction des KernelCaches
Pour tester le noyau xnu, vous devez construire un kernelcache qui lie les kexts et le noyau ensemble en une seule image amorçable.
Pour construire un kernelcache, vous pouvez utiliser les mécanismes suivants :
* Utilisation de la génération automatique de kernelcache avec `kextd`.
Le daemon kextd surveille les changements dans le répertoire `/System/Library/Extensions`.
Vous pouvez ainsi configurer un nouveau noyau comme suit :
```text
cp BUILD/obj/DEVELOPMENT/X86_64/kernel.development /System/Library/Kernels/
touch /System/Library/Extensions
ps -e | grep kextd
```
* Invocation manuelle de `kextcache` pour construire un nouveau kernelcache.
```text
kextcache -q -z -a x86_64 -l -n -c /var/tmp/kernelcache.test -K /var/tmp/kernel.test /System/Library/Extensions
```
## Amorçage d'un KernelCache sur une machine cible
Le noyau de développement et iBoot prennent en charge la configuration des arguments de démarrage afin de pouvoir démarrer en toute sécurité sur le noyau de test et, en cas de problème, revenir en toute sécurité au kernelcache précédemment utilisé.
Voici les étapes pour obtenir une telle configuration :
1. Créez le cache du noyau à l'aide de la commande kextcache sous `/kernelcache.test`
2. Copiez les configurations de démarrage existantes dans un fichier alternatif
```sh
cp /Library/Preferences/SystemConfiguration/com.apple.Boot.plist /next_boot.plist
```
3. Mettez à jour le kernelcache et les boot-args pour votre configuration
```sh
plutil -insert "Kernel Cache" -string "kernelcache.test" /next_boot.plist
plutil -replace "Kernel Flags" -string "debug=0x144 -v kernelsuffix=test " /next_boot.plist
```
4. Copiez la nouvelle configuration dans `/Library/Preferences/SystemConfiguration/`
```sh
cp /next_boot.plist /Library/Preferences/SystemConfiguration/boot.plist
```
5. Bénissez le volume avec les nouvelles configurations.
```text
sudo -n bless --mount / --setBoot --nextonly --options "config=boot"
```
Le drapeau `--nextonly` spécifie d'utiliser les configurations `boot.plist` uniquement pour un démarrage.
Ainsi, si le noyau panique, vous pouvez facilement redémarrer et revenir au noyau d'origine.
## Création de tags et cscope
Configurez votre environnement de build et, depuis le répertoire racine, exécutez :
make tags # ceci construira ctags et etags sur un volume sensible à la casse, seulement ctags sur un volume insensible
make TAGS # ceci construira etags
make cscope # ceci construira la base de données cscope
## Installation de nouveaux fichiers d'en-tête depuis XNU
XNU installe les fichiers d'en-tête aux emplacements suivants :
a. $(DSTROOT)/System/Library/Frameworks/Kernel.framework/Headers
b. $(DSTROOT)/System/Library/Frameworks/Kernel.framework/PrivateHeaders
c. $(DSTROOT)/usr/include/
d. $(DSTROOT)/usr/local/include/
e. $(DSTROOT)/System/DriverKit/usr/include/
f. $(DSTROOT)/System/Library/Frameworks/IOKit.framework/Headers
g. $(DSTROOT)/System/Library/Frameworks/IOKit.framework/PrivateHeaders
h. $(DSTROOT)/System/Library/Frameworks/System.framework/PrivateHeaders
`Kernel.framework` est utilisé par les extensions du noyau.\
Les `System.framework`, `/usr/include` et `/usr/local/include` sont utilisés par les applications au niveau utilisateur.\
`IOKit.framework` est utilisé par les clients userspace d'IOKit.\
`/System/DriverKit/usr/include` est utilisé par les pilotes userspace.\
Les fichiers d'en-tête dans `PrivateHeaders` d'un framework ne sont disponibles que pour le **développement interne Apple**.
Le répertoire contenant le fichier d'en-tête doit avoir un Makefile qui crée la liste des fichiers à installer à différents emplacements.
Si vous ajoutez le premier fichier d'en-tête dans un répertoire, vous devrez créer un Makefile similaire à `xnu/bsd/sys/Makefile`.
Ajoutez votre fichier d'en-tête à la liste de fichiers correcte en fonction de l'endroit où vous souhaitez l'installer.
Les emplacements par défaut où les fichiers d'en-tête sont installés à partir de chaque liste de fichiers sont :
a. `DATAFILES` : Pour rendre le fichier d'en-tête disponible au niveau utilisateur -
`$(DSTROOT)/usr/include`
`$(DSTROOT)/System/Library/Frameworks/System.framework/PrivateHeaders`
b. `DRIVERKIT_DATAFILES` : Pour rendre le fichier d'en-tête disponible pour les pilotes userspace DriverKit -
`$(DSTROOT)/System/DriverKit/usr/include`
c. `PRIVATE_DATAFILES` : Pour rendre le fichier d'en-tête disponible pour le développement interne Apple au
niveau utilisateur -
`$(DSTROOT)/System/Library/Frameworks/System.framework/PrivateHeaders`
d. `EMBEDDED_PRIVATE_DATAFILES` : Pour rendre le fichier d'en-tête disponible au niveau utilisateur
pour macOS comme `EXTRA_DATAFILES`, mais pour le développement interne Apple au niveau utilisateur
pour les OS embarqués comme `EXTRA_PRIVATE_DATAFILES` -
`$(DSTROOT)/usr/include` (`EXTRA_DATAFILES`)
`$(DSTROOT)/usr/local/include` (`EXTRA_PRIVATE_DATAFILES`)
e. `KERNELFILES` : Pour rendre le fichier d'en-tête disponible au niveau noyau -
`$(DSTROOT)/System/Library/Frameworks/Kernel.framework/Headers`
`$(DSTROOT)/System/Library/Frameworks/Kernel.framework/PrivateHeaders`
f. `PRIVATE_KERNELFILES` : Pour rendre le fichier d'en-tête disponible pour le développement interne Apple
pour les extensions du noyau -
`$(DSTROOT)/System/Library/Frameworks/Kernel.framework/PrivateHeaders`
g. `MODULEMAPFILES` : Pour rendre le fichier de module map disponible au niveau utilisateur -
`$(DSTROOT)/usr/include`
h. `PRIVATE_MODULEMAPFILES` : Pour rendre le fichier de module map disponible pour le développement
interne Apple au niveau utilisateur -
`$(DSTROOT)/usr/local/include`
i. `LIBCXX_DATAFILES` : Pour rendre le fichier d'en-tête disponible pour les clients libcxx dans le noyau :
`$(DSTROOT)/System/Library/Frameworks/Kernel.framework/PrivateHeaders/kernel_sdkroot`
j. `EXCLAVEKIT_DATAFILES` : Pour rendre le fichier d'en-tête disponible pour le développement interne Apple
SDK ExclaveKit -
`$(DSTROOT)/System/ExclaveKit/usr/include`
k. `EXCLAVECORE_DATAFILES` : Pour rendre le fichier d'en-tête disponible pour le développement interne Apple
SDK ExclaveCore -
`$(DSTROOT)/System/ExclaveCore/usr/include`
Le Makefile combine les listes de fichiers mentionnées ci-dessus en différentes listes d'installation qui sont utilisées par le système de build pour installer les fichiers d'en-tête. Il existe deux types de listes d'installation : dépendantes de la machine et indépendantes de la machine. Ces listes sont indiquées par la présence de `MD` et `MI` dans le paramètre de build, respectivement. Si votre en-tête est spécifique à une architecture, vous devez utiliser une liste d'installation dépendante de la machine (par exemple `INSTALL_MD_LIST`). Si votre en-tête doit être installé pour toutes les architectures, vous devez utiliser une liste d'installation indépendante de la machine (par exemple `INSTALL_MI_LIST`).
Si la liste d'installation qui vous intéresse n'existe pas, créez-la en ajoutant les listes de fichiers appropriées. Les listes d'installation par défaut, leurs listes de fichiers membres et leur emplacement par défaut sont décrits ci-dessous :
a. `INSTALL_MI_LIST`, `INSTALL_MODULEMAP_MI_LIST` : Installe les fichiers d'en-tête et de module map vers un emplacement accessible à tous au niveau utilisateur.
Emplacements -
$(DSTROOT)/usr/include
Définition -
INSTALL_MI_LIST = ${DATAFILES}
INSTALL_MODULEMAP_MI_LIST = ${MODULEMAPFILES}
b. `INSTALL_DRIVERKIT_MI_LIST` : Installe le fichier d'en-tête vers un emplacement accessible
aux pilotes userspace DriverKit.
Emplacements -
$(DSTROOT)/System/DriverKit/usr/include
Définition -
INSTALL_DRIVERKIT_MI_LIST = ${DRIVERKIT_DATAFILES}
c. `INSTALL_MI_LCL_LIST`, `INSTALL_MODULEMAP_MI_LCL_LIST` : Installe les fichiers d'en-tête et de
module map vers un emplacement accessible pour le développement interne Apple au niveau utilisateur.
Emplacements -
$(DSTROOT)/usr/local/include
Définition -
INSTALL_MI_LCL_LIST =
INSTALL_MODULEMAP_MI_LCL_LIST = ${PRIVATE_MODULEMAPFILES}
d. `INSTALL_IF_MI_LIST` : Installe le fichier d'en-tête vers un emplacement accessible
à tous pour les clients userspace d'IOKit.
Emplacements -
$(DSTROOT)/System/Library/Frameworks/IOKit.framework/Headers
Définition -
INSTALL_IF_MI_LIST = ${DATAFILES}
e. `INSTALL_IF_MI_LCL_LIST` : Installe le fichier d'en-tête vers un emplacement accessible
pour le développement interne Apple pour les clients userspace d'IOKit.
Emplacements -
$(DSTROOT)/System/Library/Frameworks/IOKit.framework/PrivateHeaders
Définition -
INSTALL_IF_MI_LCL_LIST = ${DATAFILES} ${PRIVATE_DATAFILES}
f. `INSTALL_SF_MI_LCL_LIST` : Installe le fichier d'en-tête vers un emplacement accessible
pour le développement interne Apple au niveau utilisateur.
Emplacements -
$(DSTROOT)/System/Library/Frameworks/System.framework/PrivateHeaders
Définition -
INSTALL_SF_MI_LCL_LIST = ${DATAFILES} ${PRIVATE_DATAFILES}
g. `INSTALL_KF_MI_LIST` : Installe le fichier d'en-tête vers un emplacement accessible
à tous pour les extensions du noyau.
Emplacements -
$(DSTROOT)/System/Library/Frameworks/Kernel.framework/Headers
Définition -
INSTALL_KF_MI_LIST = ${KERNELFILES}
h. `INSTALL_KF_MI_LCL_LIST` : Installe le fichier d'en-tête vers un emplacement accessible
pour le développement interne Apple pour les extensions du noyau.
Emplacements -
$(DSTROOT)/System/Library/Frameworks/Kernel.framework/PrivateHeaders
Définition -
INSTALL_KF_MI_LCL_LIST = ${KERNELFILES} ${PRIVATE_KERNELFILES}
i. `EXPORT_MI_LIST` : Exporte le fichier d'en-tête vers l'ensemble de xnu (bsd/, osfmk/, etc.)
pour la compilation uniquement. N'installe rien dans le SDK.
Définition -
EXPORT_MI_LIST = ${KERNELFILES} ${PRIVATE_KERNELFILES}
j. `INSTALL_KF_LIBCXX_MI_LIST` : Installe le fichier d'en-tête pour la prise en charge de libc++ dans le noyau.
Emplacements -
$(DSTROOT)/System/Library/Frameworks/Kernel.framework/PrivateHeaders/kernel_sdkroot
Définition -
INSTALL_KF_LIBCXX_MI_LIST = ${LIBCXX_DATAFILES}
k. `INSTALL_EXCLAVEKIT_MI_LIST` : Installe le fichier d'en-tête vers un emplacement accessible
pour le développement interne Apple pour ExclaveKit.
Emplacements -
$(DSTROOT)/System/ExclaveKit/usr/include
Définition -
INSTALL_EXCLAVEKIT_MI_LIST = ${EXCLAVEKIT_DATAFILES}
l. `INSTALL_EXCLAVECORE_MI_LIST` : Installe le fichier d'en-tête vers un emplacement accessible
pour le développement interne Apple pour ExclaveCore.
Emplacements -
$(DSTROOT)/System/ExclaveCore/usr/include
Définition -
INSTALL_EXCLAVECORE_MI_LIST = ${EXCLAVECORE_DATAFILES}
Si vous souhaitez installer le fichier d'en-tête dans un sous-répertoire des chemins décrits en (1), spécifiez le nom du répertoire en utilisant deux variables `INSTALL_MI_DIR` et `EXPORT_MI_DIR` comme suit -```text
INSTALL_MI_DIR = dirname
EXPORT_MI_DIR = dirname
Si vous souhaitez installer le fichier de mappe de modules dans un sous-répertoire, spécifiez le nom du répertoire en utilisant la variable INSTALL_MODULEMAP_MI_DIR comme suit -```text
INSTALL_MODULEMAP_MI_DIR = dirname
Un seul fichier d'en-tête peut exister à différents emplacements en utilisant les étapes mentionnées ci-dessus. Cependant, il peut ne pas être souhaitable de rendre tout le code du fichier d'en-tête disponible à tous les emplacements. Par exemple, vous souhaitez exporter une fonction uniquement au niveau du noyau et non au niveau utilisateur.
Vous pouvez utiliser la directive de préprocesseur du langage C (#ifdef, #endif, #ifndef)
pour contrôler le texte généré avant l'installation d'un fichier d'en-tête. Le noyau
n'inclut le code que si la macro conditionnelle est VRAIE et supprime
le code pour les conditions FAUSSES du fichier d'en-tête.
Quelques macros prédéfinies et leurs descriptions sont -
1. `PRIVATE` : Si défini, les définitions incluses sont considérées comme des interfaces privées du système. Elles sont visibles dans xnu et
exposées dans les en-têtes utilisateur/noyau installés dans les sections "PrivateHeaders" d'AppleInternal
des frameworks System et Kernel.
2. `KERNEL_PRIVATE` : Si défini, le code inclus est disponible pour l'ensemble du noyau xnu
et les extensions internes du noyau Apple, et est omis des en-têtes
utilisateur.
3. `BSD_KERNEL_PRIVATE` : Si défini, le code inclus est visible exclusivement
dans le module xnu/bsd.
4. `MACH_KERNEL_PRIVATE`: Si défini, le code inclus est visible exclusivement
dans le module xnu/osfmk.
5. `XNU_KERNEL_PRIVATE`: Si défini, le code inclus est visible exclusivement
dans xnu.
6. `KERNEL` : Si défini, le code inclus est disponible dans xnu et les extensions
du noyau et n'est pas visible dans les fichiers d'en-tête de niveau utilisateur. Seuls les
fichiers d'en-tête installés dans les chemins suivants auront le code -
```text
$(DSTROOT)/System/Library/Frameworks/Kernel.framework/Headers
$(DSTROOT)/System/Library/Frameworks/Kernel.framework/PrivateHeaders
```
7. `DRIVERKIT`: Si défini, le code inclus est visible exclusivement dans les
en-têtes du SDK DriverKit utilisés par les pilotes de l'espace utilisateur.
8. `EXCLAVEKIT`: Si défini, le code inclus est visible exclusivement dans les
en-têtes du SDK ExclaveKit.
9. `EXCLAVECORE`: Si défini, le code inclus est visible exclusivement dans les
en-têtes du SDK ExclaveCore.
10. `MODULES_SUPPORTED` Si défini, le code inclus est visible exclusivement
dans les emplacements qui prennent en charge les modules/Swift (c'est-à-dire pas les frameworks System ou Kernel).
## Convention de nommage des fichiers d'en-tête VM
Les en-têtes VM suivent les conventions de nommage suivantes :
* Les en-têtes `*_internal.h` contiennent des composants du sous-système VM uniquement destinés au code VM.
* Les en-têtes `*_xnu.h` contiennent des composants du sous-système VM uniquement destinés à d'autres codes xnu.
* Les en-têtes `*.h` contiennent des composants du sous-système VM exportés vers les kexts.
* L'en-tête `vm_iokit.h` contient des composants du sous-système VM exportés vers le sous-système iokit.
* L'en-tête `vm_ubc.h` contient des composants du sous-système VM exportés vers le sous-système ubc.
## Convention de nommage des fichiers de carte de modules
Dans le cas simple, un sous-répertoire de `usr/include` ou `usr/local/include`
peut être représenté par un module autonome. Le cas échéant, définissez
`INSTALL_MODULEMAP_MI_DIR` sur `INSTALL_MI_DIR` et installez un fichier `module.modulemap`
à cet emplacement. `module.modulemap` est utilisé même pour les modules privés dans
`usr/local/include` ; `module.private.modulemap` n'est pas utilisé. Mise en garde : pour
rester dans le cas simple, le nom du module doit être exactement le même que
le nom du répertoire. Si ce n'est pas possible, la méthode suivante devra
être appliquée.
`xnu` contribue aux modules définis dans CoreOSModuleMaps en installant
des fichiers de carte de modules provenant de `usr/include/module.modulemap` et
`usr/local/include/module.modulemap`. La convention de nommage pour les fichiers de carte de modules de
`xnu` est la suivante.
a. Idéalement, le fichier de carte de modules couvre un répertoire entier. Un fichier de carte de
modules couvrant `usr/include/a/b/c` serait nommé `a_b_c.modulemap`.
`usr/local/include/a/b/c` serait nommé `a_b_c_private.modulemap`.
b. Certains en-têtes sont spéciaux et nécessitent leur propre module. Dans ce cas,
le fichier de carte de modules serait nommé d'après le module qu'il définit.
Un fichier de carte de modules définissant le module `One.Two.Three` serait nommé
`one_two_three.modulemap`.
## Compilation conditionnelle
`xnu` offre les mécanismes suivants pour compiler du code de manière conditionnelle :
1. *Caractéristiques du processeur* Si le code que vous protégez a des
caractéristiques spécifiques qui varieront uniquement en fonction de l'architecture du processeur
ciblée, utilisez cette option. Préférez vérifier les fonctionnalités de
l'architecture (par exemple `__LP64__`, `__LITTLE_ENDIAN__`, etc.).
2. *Nouvelles fonctionnalités* Si le code que vous protégez, pris dans son ensemble,
implémente une fonctionnalité, vous devez définir une nouvelle fonctionnalité dans `config/MASTER`
et utiliser le jeton de préprocesseur `CONFIG` résultant (par exemple pour une fonctionnalité
nommée `config_virtual_memory`, vérifiez `#if CONFIG_VIRTUAL_MEMORY`).
Cette pratique garantit que les fonctionnalités existantes peuvent être portées sur d'autres
plates-formes en modifiant simplement un commutateur de fonctionnalité.
3. *Fonctionnalités existantes* Vous pouvez utiliser des fonctionnalités existantes si votre code est
fortement lié à celles-ci (par exemple, utilisez `SECURE_KERNEL` si votre code implémente
de nouvelles fonctionnalités qui sont exclusivement pertinentes pour le noyau de confiance et
met à jour la définition/la compréhension de ce que signifie être un noyau de confiance).
Il est recommandé d'éviter de compiler en fonction de la plateforme cible. `xnu`
ne définit pas les macros de plateforme de `TargetConditionals.h`
(`TARGET_OS_OSX`, `TARGET_OS_IOS`, etc.).
## Débogage de XNU
Par défaut, le noyau redémarre en cas de panique.
Ce comportement peut être remplacé par l'argument de démarrage `debug` -- `debug=0x14e` fera qu'une panique attendra qu'un débogueur s'attache.
Pour démarrer un noyau afin qu'il puisse être débogué par une machine attachée, remplacez l'argument de démarrage `kdp_match_name` par l'interface `ifconfig` appropriée.
Le débogage Ethernet, Thunderbolt et série est pris en charge, selon le matériel.
Utilisez LLDB pour déboguer le noyau :```text
xcrun -sdk macosx lldb <path-to-unstripped-kernel>
(lldb) gdb-remote [<host-ip>:]<port>
Les informations de débogage pour le noyau (dSYM) sont fournies avec un ensemble de macros pour prendre en charge le débogage du noyau. Pour charger ces macros automatiquement lors de l'attachement au noyau, ajoutez ce qui suit à ~/.lldbinit :```text
settings set target.load-script-from-symbol-file true
`tools/lldbmacros` contient le code source de ces commandes.
Consultez le README dans ce répertoire pour leur utilisation, ou utilisez l'aide intégrée de LLDB avec :```text
(lldb) help showcurrentstacks