feat(wifi): publier les médiums réseau IEEE80211/Ethernet et activer la radio par défaut (Étape 9)

- Breakthroughs & Rétro-ingénierie :
  * Analyse binaire approfondie sous LLDB de Apple80211GetIfListCopy et _getIfListCopy (0x7ffc235a38fb) dans Apple80211.framework :
    airportd exécute ioctl(SIOCGIFMEDIA, 0xc02c6938) sur chaque interface réseau BSD pour vérifier son média physique.
    Si le contrôleur ne possède pas de table de médiums, le noyau renvoie EIO (Input/output error), provoquant l'élimination
    immédiate de l'interface en1 par le filtre et le renvoi d'une liste vide (ifCount=0 / -3903).
  * Rétro-ingénierie de IO80211SkywalkInterface::getSupportedMediaArray (0xffffff80022f8e5e) dans BootKernelExtensions.kc :
    appelle le slot virtuel 0x890 du contrôleur (getMediumDictionary()). Si NULL, renvoie kIOReturnUnsupported (0xe00002c7),
    se traduisant par EIO sur SIOCGIFMEDIA.
  * Confirmation du filtre _isInfraInterface (0x7ffc235a48c9) validant que l'interface possède "IO80211InterfaceRole" == "Infrastructure".

- Modifications apportées :
  * QualcommWifi/QualcommWifi.hpp : Déclaration de selectMedium(const IONetworkMedium*) et createMediumTables().
  * QualcommWifi/QualcommWifi.cpp :
    - Implémentation de createMediumTables() : instanciation d'un OSDictionary avec kIOMediumIEEE80211Auto et kIOMediumEthernetAuto (1 Gbps),
      publication via publishMediumDictionary(), sélection via setSelectedMedium()/setCurrentMedium(), et activation du lien avec setLinkStatus().
    - Implémentation du callback virtuel selectMedium().
    - Appel de createMediumTables() dans start() avant l'enregistrement Skywalk avec traçage NVRAM s8_medium_init.
    - Activation de la radio par défaut dans init() (fLinkActive = true) pour rapporter l'état allumé (APPLE80211_S_RUN).
  * docs/ISSUES_AND_POSTMORTEMS.md : Rédaction du Postmortem 25 détaillant la résolution de l'erreur SIOCGIFMEDIA et le mécanisme de détection airportd.

- Validation :
  * ./build_wifi.sh exécuté avec succès en Release (x86_64).
  * kmutil libraries valide à 100% contre BootKernelExtensions.kc.
  * Kext déployé sur /Volumes/EFI/EFI/OC/Kexts/QualcommWifi.kext (MD5: 480ca02aff49c48afbe8b381be0c3c77).
This commit is contained in:
Erwan committed 2026-10-19 18:35:13 +02:00
1 parent 29af992874
commit 5efd0dfbae
3 files changed
+121 -1

No files matched your search

+65 -1
View File
@@ -319,7 +319,7 @@ bool QualcommWifi::init(OSDictionary *dictionary) {
fMacAddress.bytes[3] = 0x11; fMacAddress.bytes[3] = 0x11;
fMacAddress.bytes[4] = 0x07; fMacAddress.bytes[4] = 0x07;
fMacAddress.bytes[5] = 0x01; fMacAddress.bytes[5] = 0x01;
fLinkActive = false; fLinkActive = true;
fCurrentChannel = 1; fCurrentChannel = 1;
fLastRssi = -50; fLastRssi = -50;
fSsidLen = 0; fSsidLen = 0;
@@ -1071,6 +1071,10 @@ bool QualcommWifi::start(IOService *provider) {
IOLog("QualcommWifi: Publication du contrôleur contournée (qcom_step < 7 et qcom_register=0).\n"); IOLog("QualcommWifi: Publication du contrôleur contournée (qcom_step < 7 et qcom_register=0).\n");
} }
// Initialisation et publication de la table des médiums (requis pour SIOCGIFMEDIA / Apple80211GetIfListCopy)
logNvramStage("s8_medium_init");
createMediumTables();
if (skywalk_step >= 8) { if (skywalk_step >= 8) {
int substep8 = 0; int substep8 = 0;
PE_parse_boot_argn("qcom_substep", &substep8, sizeof(substep8)); PE_parse_boot_argn("qcom_substep", &substep8, sizeof(substep8));
@@ -1333,6 +1337,66 @@ IOReturn QualcommWifi::disable(IONetworkInterface *netif) {
return kIOReturnSuccess; return kIOReturnSuccess;
} }
bool QualcommWifi::createMediumTables(void) {
IOLog("QualcommWifi: Creation et publication du dictionnaire de mediums reseau...\n");
OSDictionary *mediumDict = OSDictionary::withCapacity(2);
if (!mediumDict) {
IOLog("QualcommWifi: ERREUR allocation mediumDict !\n");
return false;
}
IONetworkMedium *mediumWifi = IONetworkMedium::medium(
kIOMediumIEEE80211Auto,
1000000000ULL, // 1 Gbps
0,
0,
"Auto"
);
IONetworkMedium *mediumEth = IONetworkMedium::medium(
kIOMediumEthernetAuto,
1000000000ULL,
0,
1,
"EthernetAuto"
);
if (mediumWifi) {
IONetworkMedium::addMedium(mediumDict, mediumWifi);
mediumWifi->release();
}
if (mediumEth) {
IONetworkMedium::addMedium(mediumDict, mediumEth);
mediumEth->release();
}
bool published = publishMediumDictionary(mediumDict);
if (published) {
const IONetworkMedium *selected = IONetworkMedium::getMediumWithType(mediumDict, kIOMediumIEEE80211Auto);
if (!selected) {
selected = IONetworkMedium::getMediumWithType(mediumDict, kIOMediumEthernetAuto);
}
if (selected) {
setSelectedMedium(selected);
setCurrentMedium(selected);
setLinkStatus(kIONetworkLinkValid | kIONetworkLinkActive, selected, 1000000000ULL, nullptr);
IOLog("QualcommWifi: Medium selectionne et linkStatus(Active) configure avec succes !\n");
}
} else {
IOLog("QualcommWifi: ERREUR publishMediumDictionary !\n");
}
mediumDict->release();
return published;
}
IOReturn QualcommWifi::selectMedium(const IONetworkMedium *medium) {
if (!medium) return kIOReturnBadArgument;
setSelectedMedium(medium);
setCurrentMedium(medium);
setLinkStatus(kIONetworkLinkValid | kIONetworkLinkActive, medium);
return kIOReturnSuccess;
}
UInt32 QualcommWifi::outputPacket(mbuf_t m, void *param) { UInt32 QualcommWifi::outputPacket(mbuf_t m, void *param) {
logNvramStage("cb_outputPacket"); logNvramStage("cb_outputPacket");
if (m) { if (m) {
+4
View File
@@ -282,6 +282,10 @@ public:
// Dispatcher de requêtes Apple80211 / airportd // Dispatcher de requêtes Apple80211 / airportd
SInt32 handleApple80211Request(unsigned int req_type, int req_val, void* req_data); SInt32 handleApple80211Request(unsigned int req_type, int req_val, void* req_data);
// Gestion des Médiums Réseau (IONetworkController / SIOCGIFMEDIA)
virtual IOReturn selectMedium(const IONetworkMedium *medium) override;
bool createMediumTables(void);
}; };
#endif #endif
+52
View File
@@ -1008,3 +1008,55 @@ Ce document répertorie de manière exhaustive l'ensemble des anomalies, blocage
- Kext déployé sur l'EFI (`/Volumes/EFI/EFI/OC/Kexts/QualcommWifi.kext`). - Kext déployé sur l'EFI (`/Volumes/EFI/EFI/OC/Kexts/QualcommWifi.kext`).
- Configuration OpenCore activée : `qcom_step=8 qcom_substep=5`. - Configuration OpenCore activée : `qcom_step=8 qcom_substep=5`.
---
### Postmortem 25 : Résolution de l'Erreur SIOCGIFMEDIA (`EIO`), Rétro-ingénierie d'`Apple80211GetIfListCopy` et Publication des Médiums Réseau (Étape 9)
* **Date** : 19 Octobre 2026
* **Cible** : macOS Tahoe 26.x (Darwin 25.6.0 x86_64), AMD Ryzen 7 5800X3D, `QualcommWifi.kext` (WCN7850 `0x17cb:0x1107`)
* **Symptômes & Retours Utilisateur (/grill-me)** :
- Démarrage sans freeze ni crash validé à 100% avec l'Étape 8.
- L'interface BSD `en1` existe dans `ifconfig` et est reconnue par `networksetup -listallhardwareports` comme `Hardware Port: Wi-Fi`.
- Cependant, l'icône Wi-Fi ne s'affiche pas encore dans la barre des menus macOS, et `networksetup -getairportpower en1` affiche `Wi-Fi Power (en1): Off (forced)`.
- La commande `ifconfig en1` renvoie : `ifconfig: SIOCGIFXMEDIA: Input/output error`.
* **Breakthroughs & Rétro-ingénierie Binaire Exhaustive (`Apple80211.framework` & `BootKernelExtensions.kc`)** :
1. **Dissection de `Apple80211GetIfListCopy` et `_getIfListCopy` sous LLDB** :
- `airportd` appelle `Apple80211GetIfListCopy` pour dresser la liste des interfaces Wi-Fi.
- Dans `_getIfListCopy` (`0x7ffc235a38fb`), après avoir énuméré les interfaces via `getifaddrs()`, il exécute systématiquement :
```assembly
0x7ffc235a3ba4: callq ioctl ; ioctl(fd, 0xc02c6938 / SIOCGIFMEDIA, &ifmr)
0x7ffc235a3ba9: movl %eax, %r13d
...
0x7ffc235a3cc3: testl %r13d, %r13d
0x7ffc235a3cc6: je 0x7ffc235a4002 ; Si succès (0) -> ajoute l'interface à la liste !
0x7ffc235a3cde: jne 0x7ffc235a4091 ; Si échec (EIO) -> IGNORE L'INTERFACE !
```
- Si `SIOCGIFMEDIA` renvoie une erreur (autre que `ENOTSUP`), l'interface est purement et simplement éliminée du filtrage. `Apple80211GetIfListCopy` retourne alors `-3903` (`ifCount = 0`).
2. **Dissection de `IO80211SkywalkInterface::getSupportedMediaArray` (`0xffffff80022f8e5e`)** :
- Lors du traitement noyau de `SIOCGIFMEDIA` par `IOSkywalkNetworkInterface::ioctl_gifmedia` (`0xffffff8002b0ae78`), le noyau invoque `getSupportedMediaArray`.
- Dans `IO80211SkywalkInterface::getSupportedMediaArray` :
```assembly
0xffffff80022f8e80: mov rax, qword ptr [rdi] ; rdi = controller (QualcommWifi)
0xffffff80022f8e83: call qword ptr [rax + 0x890] ; Slot 0x890 = getMediumDictionary()
0xffffff80022f8e89: test rax, rax
0xffffff80022f8e8c: je 0xffffff80022f8f24 ; SI NULL -> ERREUR EIO !
```
- Faute d'un dictionnaire de médiums publié, le noyau renvoie inconditionnellement `EIO`.
3. **Vérification du Rôle de l'Interface (`_isInfraInterface`)** :
- Dès que `SIOCGIFMEDIA` réussit, `Apple80211GetIfListCopy` invoque `_isInfraInterface` (`0x7ffc235a48c9`).
- `_isInfraInterface` recherche le service correspondant via `{ "IOPropertyMatch" = { "IOInterfaceName" = "en1" } }` et vérifie `"IO80211InterfaceRole" == "Infrastructure"`, propriété déjà configurée avec succès sur notre `IO80211SkywalkInterface`.
* **Résolutions Techniques Appliquées dans `QualcommWifi`** :
1. **Création et Publication de la Table des Médiums (`createMediumTables`)** :
- Instanciation d'un `OSDictionary` avec les médiums `kIOMediumIEEE80211Auto` et `kIOMediumEthernetAuto` (1 Gbps) via `IONetworkMedium::medium(...)`.
- Publication auprès du noyau via `publishMediumDictionary(mediumDict)`.
- Configuration du médium sélectionné et actif via `setSelectedMedium`, `setCurrentMedium` et `setLinkStatus(kIONetworkLinkValid | kIONetworkLinkActive)`.
2. **Implémentation de `selectMedium(const IONetworkMedium *medium)`** :
- Prise en charge des requêtes de changement de média du sous-système réseau.
3. **Activation de la Radio par Défaut (`fLinkActive = true`)** :
- Initialisation à `true` dès `QualcommWifi::init()`.
- Réponses immédiates `APPLE80211_S_RUN` à `APPLE80211_IOC_STATE` et `power_state[0] = 1` à `APPLE80211_IOC_POWER`.
4. **Validation Binaire & Déploiement** :
- Compilation `Release` validée à 100% par `kmutil libraries`.
- Binaire déployé sur `/Volumes/EFI/EFI/OC/Kexts/QualcommWifi.kext` (MD5: `480ca02aff49c48afbe8b381be0c3c77`).