- 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.
11 KiB
11 KiB
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_RESERVEDIONetworkController2Evjusqu'à7Ev. - Cause Racine :
Dans le Kernel Collection
BootKernelExtensions.kcde 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: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'
IO80211Controllercomptait 448 entrées. Sous macOS Tahoe 26.x (Darwin 25), elle a été portée à 466 entrées (taille binaire de0xe90= 3728 octets). Tout écart dimensionnel invalide la correspondance des slots mémoires. - Résolution :
Vérification systématique par script de la vtable
__ZTV12QualcommWificontreBootKernelExtensions.kc. Tous les slots jusqu'à l'offset0xe90sont rigoureusement alignés sur l'ABI Tahoe.
INC-03 : Échec de IO80211Controller::start sans WorkQueue
- Symptôme :
Le pilote démarrait dans
init()etprobe(), maisIO80211Controller::startaffichaitIO80211Controller::start failset retournaitfalse. - Cause Racine :
L'analyse désassemblée de
IO80211Controller::start(0xffffff8002291f30) a révélé qu'à l'offset+0x41, le code teste le retour deIONetworkController::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: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'adresse0xffffff8002291f30dansBootKernelExtensions.kc:- À
+0x272, le pilote invoquefindAndAttachToFaultReporter()(0xffffff8002292628). - À
+0x13e, cette routine appelle la méthode virtuellethis->getFaultReporterFromDriver()(callq *0xd80(%rax), vtable slot 434). - Notre code renvoyait initialement
nullptr. - À l'adresse
0xffffff8002292737(+0x227),findAndAttachToFaultReportercontient un appel direct et inconditionnel à_panic:panic("\"No ivars->_faultReporter\" @%s:%d", "IO80211Controller.cpp", 2877) - Faute d'argument empêchant le redémarrage, macOS déclenchait immédiatement un hardware reset.
- À
- Résolution :
- Instanciation dans
init()d'un objetOSObjectvalide :fFaultReporter = OSString::withCString("QualcommFaultReporter"); - Surcharge de
getFaultReporterFromDriver()retournantfFaultReporter. - Libération propre dans
free()viaOSSafeReleaseNULL(fFaultReporter). - Dans le noyau,
findAndAttachToFaultReporter()constate que le pointeur est non-nul, stocke l'adresse dansivars->_faultReporter, incrémente la référence viaobj->retain()(*0x20(%rax)), et aucun panic n'est émis.
- Instanciation dans
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 appellethis->getLogger()(vtable slot 426,*0xd40(%rax)). Si ce pointeur est nul, elle saute directement en erreur (+0x12f), détruit le descripteur et renvoieNULL. - Résolution :
Instanciation dans
init()d'un objetfLogger = OSString::withCString("QualcommLogger"), et implémentation degetLogger()retournant(void*)fLogger.RNGAgenteffectue son appellogger->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,OSBundleRequiredavait été temporairement passé àRoot. Or,IO80211Family.kextd'Apple spécifie impérativementNetwork-Root. DéclarerRootforce 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 :
<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 :
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 :
#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=0dans lesboot-argsOpenCore du fichierconfig.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).