docs: dump comprehensive research, kernel reverse-engineering and post-mortems

- Breakthroughs & Rétro-ingénierie :
  * Création de docs/RESEARCH_AND_REVERSE_ENGINEERING.md : synthèse exhaustive
    de toutes les recherches théoriques, des contraintes matérielles du WCN7850
    (MMIO BAR0 windowing 0x310c, DMA 36-bit page mask, désactivation ASPM L0s/L1),
    de la machine d'état du protocole MHI/BHIe (bootloader 2-étapes FBC, anneaux
    CR/ER/TR, environnement d'exécution AMSS/WFW), ainsi que du reverse-engineering
    complet de l'ABI et de la vtable IO80211Controller (3728 octets, 466 entrées,
    graphe d'appels de start(), slots purs et ivars dans BootKernelExtensions.kc).
  * Création de docs/ISSUES_AND_POSTMORTEMS.md : historique détaillé et
    chronologique de l'ensemble des 9 incidents, bugs et panics rencontrés
    depuis le début du projet (erreurs de link KPI, padslot mismatch OpenCore,
    panique explicite Apple _panic("No ivars->_faultReporter"), échec RNGAgent,
    cycle Kext OSBundleRequired Network-Root, et reboots intempestifs), avec
    symptômes, analyses de cause racine, et résolutions techniques validées.
  * Mise à jour de docs/ARCHITECTURE.md : référencement croisé des nouveaux
    documents d'ingénierie et de post-mortems.

- Validation :
  * Arborescence documentaire consolidée et intègre.
  * Validation syntaxique et liens Markdown vérifiés.
This commit is contained in:
Erwan committed 2026-10-17 20:00:22 +02:00
1 parent 5357ca61fe
commit d152d81d79
3 files changed
+323

No files matched your search

+11
View File
@@ -103,3 +103,14 @@ Le pilote est structuré en deux classes IOKit distinctes et complémentaires au
5. Envoi d'un `HCI_Reset` (`0x03, 0x0c, 0x00`) via requête de contrôle USB. 5. Envoi d'un `HCI_Reset` (`0x03, 0x0c, 0x00`) via requête de contrôle USB.
6. Injection des métadonnées `IORegistry` (`USB Product Name`, `kUSBHostPortType=255`, spoofing `idVendor=0x0a12`). 6. Injection des métadonnées `IORegistry` (`USB Product Name`, `kUSBHostPortType=255`, spoofing `idVendor=0x0a12`).
7. Fermeture propre des pipes et libération de l'accès exclusif afin que le daemon `bluetoothd` prenne la main sans conflit. 7. Fermeture propre des pipes et libération de l'accès exclusif afin que le daemon `bluetoothd` prenne la main sans conflit.
---
## 3. Documentation Complémentaire & Analyse Approfondie
- [Recherche Approfondie & Rétro-Ingénierie Kernel](file:///Users/erwan/Documents/QualcommWireless/docs/RESEARCH_AND_REVERSE_ENGINEERING.md) : Analyse binaire de `BootKernelExtensions.kc`, ABI `IO80211Controller`, call graph de `start()`, slots de vtable et spécifications MHI/BHIe.
- [Historique des Problèmes & Post-Mortems](file:///Users/erwan/Documents/QualcommWireless/docs/ISSUES_AND_POSTMORTEMS.md) : Analyse détaillée des panics (`_faultReporter`, WorkQueue, vtables, ASPM, DMA 36-bit) et résolutions techniques.
- [Implémentation Wi-Fi Natif](file:///Users/erwan/Documents/QualcommWireless/docs/NATIVE_WIFI.md) : Détails sur l'architecture Skywalk et les commandes Apple80211.
- [Implémentation Bluetooth 5.4](file:///Users/erwan/Documents/QualcommWireless/docs/BLUETOOTH.md) : Détails sur le protocole DFU Qualcomm et l'injection IORegistry.
- [Guide de Compilation](file:///Users/erwan/Documents/QualcommWireless/docs/BUILD.md) : Procédure de build, signatures et déploiement OpenCore.
+168
View File
@@ -0,0 +1,168 @@
# Historique & Post-Mortems des Problèmes Rencontrés
Ce document répertorie de manière exhaustive l'ensemble des anomalies, blocages, panics et bootloops rencontrés lors du développement du pilote natif Wi-Fi Qualcomm WCN7850 (`QualcommWifi`), avec leurs analyses techniques de cause racine et leurs résolutions vérifiées.
---
## Sommaire des Incidents
| ID | Incident / Symptôme | Composant Touché | Cause Racine | Statut |
| :--- | :--- | :--- | :--- | :--- |
| **INC-01** | Erreur d'édition de liens : symboles de réservation `IONetworkController` non résolus | Linker / KPI macOS | Méthodes virtuelles de réserve non exportées par le noyau Tahoe | **Résolu** |
| **INC-02** | Crash précoce OpenCore : `padslot mismatch` | ABI / Vtable | Vtable `IO80211Controller` allongée à 466 slots sous Darwin 25 | **Résolu** |
| **INC-03** | Échec silencieux de démarrage : `IO80211Controller::start fails` | WorkQueue / IOKit | `IONetworkController::start` requiert une `IO80211WorkQueue` | **Résolu** |
| **INC-04** | **Bootloop de 5 secondes** : réinitialisation matérielle brutale du PC | Kernel Panic Apple | `panic("No ivars->_faultReporter")` dans `findAndAttachToFaultReporter` | **Résolu** |
| **INC-05** | Échec d'allocation interne : `Failed to allocate RNG Agent` | RNG / Logger | `IO80211RNGAgent` requiert un logger non-nul lors de l'initialisation | **Résolu** |
| **INC-06** | Désynchronisation du cycle d'initialisation au boot | Cycle Kexts (`Info.plist`) | `OSBundleRequired` positionné à `Root` au lieu de `Network-Root` | **Résolu** |
| **INC-07** | Blocage du chargement firmware AMSS lors du téléversement BHIe | PCIe ASPM | Désynchronisation BAR0 causée par les transitions d'énergie L0s/L1 | **Résolu** |
| **INC-08** | Corruptions mémoires & gel sur plateforme AMD avec > 4 Go RAM | Moteur DMA 36-bit | Pointeur DMA physique tronqué au-delà de 64 Go | **Résolu** |
| **INC-09** | Impossibilité de lire les rapports de panique (redémarrage instantané) | OpenCore / NVRAM | Paramètres de débogage du noyau par défaut provoquant un reboot | **Résolu** |
---
## Détail des Post-Mortems
### INC-01 : Erreur d'édition de liens sur les réservations `IONetworkController`
* **Symptôme** :
Lors de la compilation et de l'édition de liens du binaire Mach-O Kext, le compilateur Clang échouait avec des erreurs `Undefined symbols for architecture x86_64` :
`_ZN19IONetworkController29_RESERVEDIONetworkController2Ev` jusqu'à `7Ev`.
* **Cause Racine** :
Dans le Kernel Collection `BootKernelExtensions.kc` de macOS Tahoe, Apple conserve les slots virtuels de réservation pour préserver l'ABI C++, mais n'exporte pas leurs symboles dans les tables d'exportation globales (`libkern`/`KPI`).
* **Résolution** :
Définition de stubs d'export locaux C dans [`QualcommWifi.cpp`](file:///Users/erwan/Documents/QualcommWireless/QualcommWifi/QualcommWifi.cpp) :
```cpp
extern "C" {
void _ZN19IONetworkController29_RESERVEDIONetworkController2Ev(void) {}
void _ZN19IONetworkController29_RESERVEDIONetworkController3Ev(void) {}
void _ZN19IONetworkController29_RESERVEDIONetworkController4Ev(void) {}
void _ZN19IONetworkController29_RESERVEDIONetworkController5Ev(void) {}
void _ZN19IONetworkController29_RESERVEDIONetworkController6Ev(void) {}
void _ZN19IONetworkController29_RESERVEDIONetworkController7Ev(void) {}
}
```
---
### INC-02 : Crash OpenCore `padslot mismatch` sur la Vtable
* **Symptôme** :
Le Kext provoquait un plantage immédiat au chargement par OpenCore ou un KP dans `Vtables.c`.
* **Cause Racine** :
OpenCore valide strictement la taille de la table de fonctions virtuelles de chaque classe dérivée. Sous macOS Sonoma/Sequoia (Darwin 24), la vtable d'`IO80211Controller` comptait 448 entrées. Sous macOS Tahoe 26.x (Darwin 25), elle a été portée à 466 entrées (taille binaire de `0xe90` = 3728 octets). Tout écart dimensionnel invalide la correspondance des slots mémoires.
* **Résolution** :
Vérification systématique par script de la vtable `__ZTV12QualcommWifi` contre `BootKernelExtensions.kc`. Tous les slots jusqu'à l'offset `0xe90` sont rigoureusement alignés sur l'ABI Tahoe.
---
### INC-03 : Échec de `IO80211Controller::start` sans WorkQueue
* **Symptôme** :
Le pilote démarrait dans `init()` et `probe()`, mais `IO80211Controller::start` affichait `IO80211Controller::start fails` et retournait `false`.
* **Cause Racine** :
L'analyse désassemblée de `IO80211Controller::start` (`0xffffff8002291f30`) a révélé qu'à l'offset `+0x41`, le code teste le retour de `IONetworkController::start(provider)`. Cette dernière exige impérativement un gestionnaire de queue de travail valide pour instancier ses boucles d'événements.
* **Résolution** :
Implémentation des surcharges de création de la file de travail dans [`QualcommWifi.cpp`](file:///Users/erwan/Documents/QualcommWireless/QualcommWifi/QualcommWifi.cpp) :
```cpp
bool QualcommWifi::createWorkQueue(void) {
if (!fWorkQueue) {
fWorkQueue = IO80211WorkQueue::workQueue();
}
return (fWorkQueue != nullptr);
}
IO80211WorkQueue* QualcommWifi::getWorkQueue(void) const { return fWorkQueue; }
bool QualcommWifi::createWorkLoop(void) { return createWorkQueue(); }
IOWorkLoop* QualcommWifi::getWorkLoop(void) const { return getWorkQueue(); }
```
---
### INC-04 : Le Bootloop de 5 Secondes - Kernel Panic `_faultReporter`
* **Symptôme** :
L'utilisateur subissait un redémarrage en boucle constant du Mac : OpenCore se lance, commence le chargement de macOS, puis au bout de 5 secondes environ, le PC s'éteint et redémarre instantanément sans message visible.
* **Cause Racine (Breakthrough Majeur)** :
Désassemblage complet du flux de `IO80211Controller::start` à l'adresse `0xffffff8002291f30` dans `BootKernelExtensions.kc` :
1. À `+0x272`, le pilote invoque `findAndAttachToFaultReporter()` (`0xffffff8002292628`).
2. À `+0x13e`, cette routine appelle la méthode virtuelle `this->getFaultReporterFromDriver()` (`callq *0xd80(%rax)`, vtable slot 434).
3. Notre code renvoyait initialement `nullptr`.
4. À l'adresse `0xffffff8002292737` (`+0x227`), `findAndAttachToFaultReporter` contient un appel direct et inconditionnel à `_panic` :
```text
panic("\"No ivars->_faultReporter\" @%s:%d", "IO80211Controller.cpp", 2877)
```
5. Faute d'argument empêchant le redémarrage, macOS déclenchait immédiatement un hardware reset.
* **Résolution** :
1. Instanciation dans `init()` d'un objet `OSObject` valide :
```cpp
fFaultReporter = OSString::withCString("QualcommFaultReporter");
```
2. Surcharge de `getFaultReporterFromDriver()` retournant `fFaultReporter`.
3. Libération propre dans `free()` via `OSSafeReleaseNULL(fFaultReporter)`.
4. Dans le noyau, `findAndAttachToFaultReporter()` constate que le pointeur est non-nul, stocke l'adresse dans `ivars->_faultReporter`, incrémente la référence via `obj->retain()` (`*0x20(%rax)`), et **aucun panic n'est émis**.
---
### INC-05 : Échec d'allocation `IO80211RNGAgent` / `getLogger()`
* **Symptôme** :
Échec dans `IO80211Controller::start` à l'étape d'initialisation du générateur aléatoire Wi-Fi avec le log : `Failed to allocate RNG Agent`.
* **Cause Racine** :
L'inspection binaire de `IO80211RNGAgent::withOptions()` (`0xffffff80022dd55c`) a montré qu'à l'offset `+0xe6`, la fonction appelle `this->getLogger()` (vtable slot 426, `*0xd40(%rax)`). Si ce pointeur est nul, elle saute directement en erreur (`+0x12f`), détruit le descripteur et renvoie `NULL`.
* **Résolution** :
Instanciation dans `init()` d'un objet `fLogger = OSString::withCString("QualcommLogger")`, et implémentation de `getLogger()` retournant `(void*)fLogger`. `RNGAgent` effectue son appel `logger->retain()` et s'initialise avec succès.
---
### INC-06 : Mésalignement du Cycle Kext `OSBundleRequired`
* **Symptôme** :
Tentative de matching du pilote PCI trop précoce lors de la séquence de boot, provoquant des échecs d'allocation de services réseau.
* **Cause Racine** :
Dans [`Info.plist`](file:///Users/erwan/Documents/QualcommWireless/QualcommWifi/Info.plist), `OSBundleRequired` avait été temporairement passé à `Root`. Or, `IO80211Family.kext` d'Apple spécifie impérativement `Network-Root`. Déclarer `Root` force le chargement du pilote avant que la pile des protocoles réseau et des sockets du noyau ne soit prête.
* **Résolution** :
Rétablissement strict de :
```xml
<key>OSBundleRequired</key>
<string>Network-Root</string>
```
---
### INC-07 : Blocage du Téléversement BHIe par ASPM PCIe
* **Symptôme** :
Timeout lors du transfert de l'image AMSS complète (~6 Mo) via BHIe, le statut BHI restant figé en boucle.
* **Cause Racine** :
La gestion d'énergie active du bus PCIe (Active State Power Management - ASPM) tente de basculer la liaison en veille L0s ou L1 pendant les transferts DMA volumineux, corrompant les accès aux registres MMIO de notification de sonnette (`ATH12K_BHIE_TXVECDB`).
* **Résolution** :
Désactivation dynamique d'ASPM avant tout transfert firmware :
```cpp
UInt8 pciCapOffset = 0;
if (fPciDevice->findPCICapability(kIOPCIPCIExpressCapability, &pciCapOffset) && pciCapOffset != 0) {
UInt16 linkCtrl = fPciDevice->configRead16(pciCapOffset + 0x10);
linkCtrl &= ~0x3; // Désactive L0s et L1
fPciDevice->configWrite16(pciCapOffset + 0x10, linkCtrl);
}
```
---
### INC-08 : Échec et Corruption DMA sur Plateformes AMD 64-bit (> 4 Go RAM)
* **Symptôme** :
Gel ou reboot brutal lors de l'accès aux anneaux de commandes ou lors du démarrage du Primary Boot Loader.
* **Cause Racine** :
Le SoC WCN7850 possède une unité DMA adressable sur 36 bits maximum (plage physique `0x000000000` à `0xFFFFFF000`). Sur les cartes mères équipées de 32 Go ou 64 Go de RAM, les allocations kernel classiques peuvent renvoyer des tampons au-dessus de 64 Go. Les bits de poids fort étaient tronqués par le matériel, écrivant dans des zones mémoires arbitraires du noyau.
* **Résolution** :
Toutes les allocations DMA contiguës sont contraintes par un masque physique 36 bits :
```cpp
#define ATH12K_DMA_MASK_36BIT_PAGE 0xFFFFFF000ULL
IOBufferMemoryDescriptor::inTaskWithPhysicalMask(
kernel_task,
kIODirectionInOut | kIOMemoryPhysicallyContiguous,
size,
ATH12K_DMA_MASK_36BIT_PAGE
);
```
---
### INC-09 : Redémarrages Automatiques Invisibles sans Affichage de KP
* **Symptôme** :
En cas de panic du noyau, le PC redémarrait instantanément sans donner le temps à l'utilisateur de lire la pile d'appels ou la cause du crash.
* **Cause Racine** :
Par défaut, le noyau XNU sous OpenCore réinitialise le processeur en cas de panique non interceptée.
* **Résolution** :
Injection de `panic=0` dans les `boot-args` OpenCore du fichier `config.plist`. En cas d'erreur critique, le noyau gèle l'affichage, permettant de lire textuellement le fichier source et la ligne fautive (ex: `IO80211Controller.cpp:2877`).
+144
View File
@@ -0,0 +1,144 @@
# Recherche Approfondie & Rétro-Ingénierie : Qualcomm WCN7850 & macOS Tahoe (Darwin 25)
Ce document consigne l'ensemble des recherches théoriques, des analyses matérielles, du reverse-engineering binaire du noyau macOS et des découvertes d'ABI effectuées pour le développement du pilote Wi-Fi natif `QualcommWifi`.
---
## 1. Matériel & Architecture PCIe du Qualcomm WCN7850
### 1.1. Identification Matérielle
* **Puce** : Qualcomm FastConnect 7800 (WCN7850)
* **Identifiants PCI** :
* Vendor ID : `0x17cb` (Qualcomm Inc.)
* Device ID : `0x1107` (WCN7850 Wi-Fi 7 PCIe Adapter)
* Subsystem Vendor : `0x0000`, Subsystem ID : `0x0000`
* **Architecture Dual-Radio** :
* La puce intègre sur le même die le contrôleur Wi-Fi 7 (connecté via bus PCIe Gen 3/4) et le contrôleur Bluetooth 5.4 (connecté via bus USB interne `0x0cf3:0xe005` / `0xe007` / `0xe300`).
* Le Bluetooth fonctionne de manière autonome via `QualcommWireless.kext` (transport USB HCI + patches BlueToolFixup).
### 1.2. Espace Mémoire MMIO BAR0 & Mécanisme de Fenêtrage PCIe
Le contrôleur PCIe n'expose qu'une région BAR0 de 512 Ko (`0x80000` octets). L'architecture interne du WCN7850 (SoC, processeurs AMSS, mémoires partagées, registres MHI) nécessite un adressage sur plus de 8 Mo.
* **Registre de sélection de fenêtre BAR0** : `0x310c` (`ATH12K_PCI_WINDOW_REG_ADDRESS`).
* **Algorithme de fenêtrage dynamique** :
Pour tout offset matériel $A \ge \text{0x80000}$ :
$$\text{window} = (A \gg 19) \ \& \ 0x3F$$
$$\text{window\_reg\_val} = 0x80000000 \ | \ \text{window}$$
$$\text{bar0\_target\_offset} = 0x80000 \ | \ (A \ \& \ 0x7FFFF)$$
* **Observation** : Le bit 31 (`0x80000000`) valide la sélection de la fenêtre active. Le pilote maintient un cache `fCurrWindow` pour éviter des écritures redondantes sur le bus PCIe.
### 1.3. Contraintes DMA 36-bit sur Architecture AMD x86_64
* Le moteur DMA interne du WCN7850 utilise des pointeurs physiques limités à 36 bits d'adresse (`ATH12K_DMA_MASK_36BIT_PAGE` = `0xFFFFFF000ULL`, soit 64 Go d'espace physique adressable).
* Tout tampon alloué sans masque physique au-delà de 64 Go entraîne des écritures DMA tronquées, provoquant des corruptions de mémoire ou des redémarrages instantanés.
* **Règle absolue** : Les buffers DMA d'anneaux MHI et de transfert firmware doivent impérativement être instanciés via :
```cpp
IOBufferMemoryDescriptor::inTaskWithPhysicalMask(
kernel_task,
kIODirectionInOut | kIOMemoryPhysicallyContiguous,
taille,
0xFFFFFF000ULL
);
```
### 1.4. ASPM (Active State Power Management)
* Pendant le transfert du Secondary Boot Loader (SBL) ou de l'image AMSS, le passage automatique du lien PCIe en mode basse consommation (L0s ou L1) entraîne la perte de synchronisation des horloges MMIO et le blocage de la machine d'état BHIe.
* **Solution** : Désactivation explicite d'ASPM dans le registre *Link Control* de la capacité PCIe (`pciCapOffset + 0x10`) en masquant les bits 0 et 1 (`linkCtrl &= ~0x3`).
---
## 2. Protocole MHI (Modem Host Interface) & Bootloader BHI/BHIe
Le WCN7850 s'amorce à travers le protocole matériel Qualcomm MHI (Modem Host Interface) :
### 2.1. Environnements d'Exécution (Execution Environments - EE)
* `0x00` - **PBL** : Primary Boot Loader (ROM interne au SoC).
* `0x01` - **SBL** : Secondary Boot Loader (chargé par l'hôte en RAM interne).
* `0x02` - **AMSS** : Advanced Mobile Subscriber Software (Firmware principal Mission Mode Wi-Fi 7).
* `0x03` - **RDDM** : RAM Dump Collect (mode crash/debug).
* `0x04` - **WFW** : WLAN Firmware Active.
### 2.2. Séquence de Démarrage 2-Étapes (FBC - Full Boot Flow)
1. **Découverte des offsets BHI/BHIe** :
Lecture des registres de configuration MHI :
* `ATH12K_MHI_BHIOFF` (`0x24`) : contient l'offset relatif de base de la BHI.
* `ATH12K_MHI_BHIEOFF` (`0x28`) : contient l'offset relatif de base de la BHIe.
2. **Chargement de l'étape 1 (SBL)** :
* Configuration de `ATH12K_BHI_IMGADDR_LOW` et `_HIGH` avec l'adresse physique du chunk initial de 512 Ko.
* Écriture de la taille dans `ATH12K_BHI_IMGSIZE`.
* Déclenchement par sonnette BHI : écriture de `1` dans `ATH12K_BHI_IMGTXDB`.
* Attente du statut dans `ATH12K_BHI_STATUS` (vérification du masque `0xC0000000 == 0x80000000`).
3. **Configuration des Anneaux MHI (MHI Data Structures)** :
* **Channel Context Array (CCABAP)** : tableau des 64 contextes de canaux (direction, type de transfert, buffers).
* **Event Ring Context Array (ECABAP)** : anneaux d'événements matériels (ER0 pour les événements généraux, ER1 pour les paquets de données).
* **Command Ring Context Array (CRCBAP)** : anneau de commandes WMI/MHI.
* **Doorbells MHI** : programmation des adresses matérielles de sonnette pour notifier le matériel de nouveaux descripteurs.
4. **Chargement de l'étape 2 (AMSS FBC via BHIe)** :
* Allocation d'une table vectorielle Scatter-Gather (`struct bhi_vec_entry`).
* Découpage de l'image AMSS complète (~6 Mo) en segments de 512 Ko.
* Programmation des registres `ATH12K_BHIE_TXVECADDR_LOW/HIGH`, `ATH12K_BHIE_TXVECSIZE`, et écriture de `1` dans `ATH12K_BHIE_TXVECDB`.
5. **Transition vers l'état Mission M0** :
* Écriture de l'état `ATH12K_MHI_STATE_M0` (2) dans `ATH12K_MHI_MHICTRL`.
* Surveillance des interruptions MSI et des événements d'anneau MHI (`PKT_TYPE_STATE_CHANGE_EVENT` vers M0 et `PKT_TYPE_EE_EVENT` vers `AMSS`).
---
## 3. Reverse-Engineering d'Apple `IO80211Controller` (macOS Tahoe Darwin 25)
L'analyse a été menée par rétro-ingénierie binaire directe de la Kernel Collection de production : `/System/Library/KernelCollections/BootKernelExtensions.kc`.
### 3.1. Structure de la Vtable `IO80211Controller`
* **Emplacement Vtable** : `0xffffff8002461148` à `0xffffff8002461fd8`.
* **Taille exacte** : `0xe90` octets (3728 octets) = **466 entrées** (2 mots d'en-tête RTTI + 464 slots de méthodes virtuelles).
* **Alignement OpenCore** :
OpenCore valide la taille exacte de la vtable lors du chargement des Kexts (`Vtables.c`). Tout Kext dérivant d'`IO80211Controller` sous macOS Tahoe doit impérativement avoir une table virtuelle de 3728 octets sous peine d'échec immédiat (`padslot mismatch`).
### 3.2. Méthodes Virtuelles Pures d'Apple (`___cxa_pure_virtual`)
Le noyau macOS définit 6 slots virtuels purs dans `IO80211Controller` qui **doivent obligatoirement être implémentés** par le sous-classeur :
1. `Slot 410 (*0xcc0)` : `IONetworkController::getPacketFilters`
2. `Slot 411 (*0xcc8)` : `IONetworkController::enable(IONetworkInterface*)`
3. `Slot 412 (*0xcd0)` : `IONetworkController::disable(IONetworkInterface*)`
4. `Slot 413 (*0xcd8)` : `IONetworkController::outputPacket(mbuf_t, void*)`
5. `Slot 414 (*0xce0)` : `IONetworkController::getHardwareAddress(IOEthernetAddress*)`
6. **Slot 426 (`*0xd40(%rax)`)** : `virtual void* getLogger(void) const = 0;`
7. **Slot 434 (`*0xd80(%rax)`)** : `virtual void* getFaultReporterFromDriver(void) = 0;`
### 3.3. Déroulement Interne de `IO80211Controller::start(provider)` (`0xffffff8002291f30`)
L'analyse désassemblée révèle le graphe d'appels complet exécuté lors de `super::start(provider)` :
1. `+0x03b` : Invoque `IONetworkController::start(provider)` (`0xffffff80026f34dc`).
* Initialise le WorkLoop réseau et publie les interfaces.
* **Exigence** : Nécessite que `createWorkQueue()` soit surchargé et valide, sinon `start` retourne `false` immédiatement.
2. `+0x17e` : Appelle `this->getLogger()` (`callq *0xd40(%rax)`, Slot 426).
* Stocke le résultat à l'offset `0x70` des ivars internes (`ivars->_logger`).
3. `+0x191` : Appelle `createIOReporters(provider)`.
4. `+0x25a` : Appelle `setupControlPathLogging()`.
* Vérifie les flags d'événements et de métriques LQML.
5. `+0x272` : Appelle `findAndAttachToFaultReporter()` (`0xffffff8002292628`).
* Invoque `this->getFaultReporterFromDriver()` (`callq *0xd80(%rax)`, Slot 434).
* Si le pointeur renvoyé est non-nul : appelle `obj->retain()` (`callq *0x20(%rax)`), et le stocke dans `ivars->_faultReporter` (`0x58(%ivars)`).
* **Comportement si NULL** : À `0xffffff8002292737`, exécute l'instruction de panic explicite :
`panic("\"No ivars->_faultReporter\" @IO80211Controller.cpp:2877")` !
6. `+0x2d0` : Appelle `IO80211RangingManager::initWithController(this)`.
7. `+0x2e3` : Appelle `this->getWorkQueue()` (`callq *0xc68(%rax)`).
8. `+0x2f0` : Instancie `IO80211CommandGate::allocWithParams(this, workQueue)`.
9. `+0x471` : Appelle `this->CreatePostOffice()`.
* Crée la boîte aux lettres d'événements Wi-Fi associée à la workQueue.
10. `+0x4ac` : Instancie `IO80211TimerSource::allocWithParams(2, this, workQueue)`.
11. `+0x4e3` : Instancie `IO80211TimerFactory::allocWithParams(workQueue)`.
12. `+0x502` : Appelle `IO80211RNGAgent::withOptions(this)` (`0xffffff80022dd55c`).
* Invoque à son tour `this->getLogger()`. Si nul, abandonne et renvoie `NULL`.
* Si non-nul : appelle `logger->retain()`.
13. `+0x521` : Appelle `this->allocFramePool()`.
* Récupère la taille de trame via le slot 440 (retourne `0x100` = 256).
* Alloue le pool de buffers réseau via `IO80211MallocBufferPool::withOptions()`.
14. `+0x555` : Retourne `true` (`kIOReturnSuccess`).
---
## 4. Intégration Skywalk & airportd sous macOS Tahoe
* **Suppression des interfaces réseau Ethernet pour le Wi-Fi** :
Sous macOS 26.x, le démon `airportd` ignore les interfaces Wi-Fi déclarées sous forme d'`IOEthernetInterface`. L'association et la gestion du lien s'effectuent via `IO80211SkywalkInterface`.
* **Méthodes clés de gestion d'état** :
* `handleCardSpecific` : réceptionne l'ensemble des requêtes `APPLE80211_IOC_*` provenant d'`airportd` et du Centre de Contrôle.
* `dataLinkLayerAttachComplete` : notifie le pilote dès que la couche Skywalk de transport est connectée.
* `setPOWER` / `getPOWER` : gestion logicielle de l'alimentation de l'émetteur radio.
* `getCARD_CAPABILITIES` : publication des capacités matérielles (chiffrements AES/WPA3, largeurs de bande, 802.11be EHT).