feat(wifi): instantiate and attach native IO80211SkywalkInterface for airportd integration
### Breakthroughs & Rétro-ingénierie
- **Rétro-ingénierie ABI Skywalk Tahoe (`BootKernelExtensions.kc`)** :
- Analyse désassemblée via Capstone de `IO80211Controller::attachInterface` (`0xffffff8002295fce`, slot 441) :
- Le premier argument `rsi` doit être l'instance `IO80211SkywalkInterface`.
- La fonction effectue `OSDynamicCast(IO80211SkywalkInterface, iface)`.
- Vérification du rôle d'interface : `cmp dword ptr [rcx + 0x58], 1`. Si égal à 1 (Infra / Primary Wi-Fi), le pointeur est assigné à `ivars + 0x188` (`primaryInterface`).
- Analyse de `IO80211SkywalkInterface::setInterfaceRole(unsigned int role)` (`0xffffff80022f60f0`) :
- Écrit la valeur du rôle dans `ivars + 0x58` (`mov dword ptr [rax + 0x58], esi`), satisfaisant la condition de slot 441.
- Analyse du cycle de vie de `IO80211SkywalkInterface` :
- La classe ne possède aucun slot virtuel pur (`___cxa_pure_virtual` = 0).
- Taille d'instance exacte : `0x128` (296 octets), ivars privées `0xf0` octets allouées par `initIvars()`.
- L'initialisation via `init(controller, mac)` copie l'adresse MAC physique dans `ivars + 0xe4`.
- `start(controller)` crée l'interface BSD (`en1`/`en2`), initialise `CCPipe` CoreCapture, lie le `getWorkQueue()` du contrôleur, invoque `controller->open(iface)` et instancie l'agent `IO80211MacAddressAgent`.
### Modifications apportées
- `QualcommWireless/include/IOKit/80211/IO80211SkywalkInterface.h` :
- Déclaration de l'héritage `public IOSkywalkEthernetInterface`.
- Déclaration des signatures de méthodes : `init(controller, mac)`, `setInterfaceRole(role)`, `start(controller)`, `stop(controller)`, `free()`.
- `QualcommWifi/QualcommWifi.hpp` :
- Ajout du membre `IO80211SkywalkInterface *fSkywalkInterface`.
- `QualcommWifi/QualcommWifi.cpp` :
- Déclaration des symboles externes exportés par `BootKernelExtensions.kc` (`_ZN23IO80211SkywalkInterfacenwEm`, `_ZN23IO80211SkywalkInterfaceC1EPK11OSMetaClass`, `_ZN23IO80211SkywalkInterface10gMetaClassE`).
- Fonction helper `createSkywalkInterface()` allouant l'instance avec la metaclass native.
- Dans `QualcommWifi::start()` :
- Contrôle via boot-arg `qcom_skywalk=1`.
- Instanciation de l'interface Skywalk via `createSkywalkInterface()`.
- Initialisation avec MAC physique (`fMacAddress`) et assignation du rôle 1 (`setInterfaceRole(1)`).
- Attachement IOKit (`attach(this)`), démarrage Skywalk (`start(this)`).
- Enregistrement auprès du contrôleur (`attachInterface(fSkywalkInterface, nullptr)`).
- Publication du service IOKit (`skywalk->registerService()`) pour notifier `airportd`.
- Dans `QualcommWifi::stop()` : détachement propre (`detachInterface(fSkywalkInterface, false)`), `stop()`, `detach()` et libération.
### Validation
- Compilation réussie sans warning : `clang++ -target x86_64-apple-macos26.5`.
- Validation d'édition de liens et kext dependencies : `kmutil libraries -p build/Release/QualcommWifi.kext` à 100%.
- Déploiement automatique dans `/Volumes/EFI/EFI/OC/Kexts/QualcommWifi.kext`.
- Mise à jour de `/Volumes/EFI/EFI/OC/config.plist` avec `qcom_skywalk=1` (validé par `plutil -lint`).
This commit is contained in:
1 parent
d222156c8b
commit
e4c7d59a5e
3 files changed
+74
-6
No files matched your search
@@ -128,6 +128,23 @@ static_assert(__builtin_offsetof(FakeLogStream, streamData) == 0x88, "streamData
|
||||
static_assert(__builtin_offsetof(FakeLogStream, p1) == 0x90, "p1 must be at offset 0x90 for CCLogStream ABI");
|
||||
static_assert(sizeof(FakeLogStream) == 0x98, "FakeLogStream size must match CCLogStream ABI (0x98)");
|
||||
|
||||
extern "C" {
|
||||
void* _ZN23IO80211SkywalkInterfacenwEm(unsigned long size);
|
||||
void _ZN23IO80211SkywalkInterfaceC1EPK11OSMetaClass(void *thisPtr, const void *meta);
|
||||
void _ZN23IO80211SkywalkInterfacedlEPvm(void *ptr, unsigned long size);
|
||||
extern const void * const _ZN23IO80211SkywalkInterface10gMetaClassE;
|
||||
}
|
||||
|
||||
static IO80211SkywalkInterface* createSkywalkInterface(void) {
|
||||
void *mem = _ZN23IO80211SkywalkInterfacenwEm(0x128);
|
||||
if (!mem) {
|
||||
IOLog("QualcommWifi: Erreur - operator new(IO80211SkywalkInterface) a echoue !\n");
|
||||
return nullptr;
|
||||
}
|
||||
_ZN23IO80211SkywalkInterfaceC1EPK11OSMetaClass(mem, &_ZN23IO80211SkywalkInterface10gMetaClassE);
|
||||
return (IO80211SkywalkInterface *)mem;
|
||||
}
|
||||
|
||||
#define super IO80211Controller
|
||||
OSDefineMetaClassAndStructors(QualcommWifi, IO80211Controller)
|
||||
|
||||
@@ -146,6 +163,7 @@ bool QualcommWifi::init(OSDictionary *dictionary) {
|
||||
fWorkLoop = nullptr;
|
||||
fWorkQueue = nullptr;
|
||||
fNetif = nullptr;
|
||||
fSkywalkInterface = nullptr;
|
||||
// Adresse MAC par défaut (OUI Qualcomm 00:03:7F) en attendant la lecture BHI
|
||||
fMacAddress.bytes[0] = 0x00;
|
||||
fMacAddress.bytes[1] = 0x03;
|
||||
@@ -173,6 +191,7 @@ bool QualcommWifi::init(OSDictionary *dictionary) {
|
||||
|
||||
void QualcommWifi::free(void) {
|
||||
logNvramStage("free_enter");
|
||||
OSSafeReleaseNULL(fSkywalkInterface);
|
||||
OSSafeReleaseNULL(fFaultReporter);
|
||||
OSSafeReleaseNULL(fLogger);
|
||||
OSSafeReleaseNULL(fWorkLoop);
|
||||
@@ -752,10 +771,47 @@ bool QualcommWifi::start(IOService *provider) {
|
||||
setProperty("IO80211ScanCache", true);
|
||||
setProperty("IO80211RadioState", (UInt64)1, 32);
|
||||
|
||||
// Note d'architecture Tahoe : un contrôleur IO80211Controller ne publie pas de médium Ethernet
|
||||
// et ne doit pas appeler registerService() directement (anti-patron IOKit déclenchant airportd
|
||||
// prématurément avant l'attachement d'une interface Skywalk).
|
||||
// Contrôlé par boot-arg "qcom_register=1" pour isoler et tester le matching.
|
||||
// Instanciation et attachement de l'interface réseau Skywalk native (IO80211SkywalkInterface)
|
||||
// Contrôlé par boot-arg "qcom_skywalk=1" (activé par défaut)
|
||||
int allow_skywalk = 1;
|
||||
PE_parse_boot_argn("qcom_skywalk", &allow_skywalk, sizeof(allow_skywalk));
|
||||
|
||||
if (allow_skywalk) {
|
||||
logNvramStage("skywalk_alloc");
|
||||
fSkywalkInterface = createSkywalkInterface();
|
||||
if (fSkywalkInterface) {
|
||||
logNvramStage("skywalk_init");
|
||||
if (fSkywalkInterface->init(this, (ether_addr *)&fMacAddress)) {
|
||||
logNvramStage("skywalk_role");
|
||||
fSkywalkInterface->setInterfaceRole(1); // 1 = kIO80211InterfaceRoleInfra (Primary Wi-Fi)
|
||||
logNvramStage("skywalk_attach");
|
||||
if (fSkywalkInterface->attach(this)) {
|
||||
logNvramStage("skywalk_start");
|
||||
if (fSkywalkInterface->start(this)) {
|
||||
logNvramStage("skywalk_attach_ctrl");
|
||||
attachInterface(fSkywalkInterface, nullptr); // slot 441 in IO80211Controller
|
||||
logNvramStage("skywalk_register");
|
||||
fSkywalkInterface->registerService();
|
||||
IOLog("QualcommWifi: Interface Skywalk native (IO80211SkywalkInterface) attachée et enregistrée avec succès !\n");
|
||||
} else {
|
||||
logNvramStage("skywalk_start_err");
|
||||
IOLog("QualcommWifi: Erreur - fSkywalkInterface->start(this) a échoué !\n");
|
||||
fSkywalkInterface->detach(this);
|
||||
OSSafeReleaseNULL(fSkywalkInterface);
|
||||
}
|
||||
} else {
|
||||
logNvramStage("skywalk_attach_err");
|
||||
IOLog("QualcommWifi: Erreur - fSkywalkInterface->attach(this) a échoué !\n");
|
||||
OSSafeReleaseNULL(fSkywalkInterface);
|
||||
}
|
||||
} else {
|
||||
logNvramStage("skywalk_init_err");
|
||||
IOLog("QualcommWifi: Erreur - fSkywalkInterface->init(...) a échoué !\n");
|
||||
OSSafeReleaseNULL(fSkywalkInterface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int allow_register = 0;
|
||||
PE_parse_boot_argn("qcom_register", &allow_register, sizeof(allow_register));
|
||||
|
||||
@@ -774,6 +830,13 @@ bool QualcommWifi::start(IOService *provider) {
|
||||
void QualcommWifi::stop(IOService *provider) {
|
||||
IOLog("QualcommWifi: Arret du pilote Wi-Fi natif, liberation MSI, DMA et BAR0.\n");
|
||||
|
||||
if (fSkywalkInterface) {
|
||||
detachInterface(fSkywalkInterface, false); // slot 442 in IO80211Controller
|
||||
fSkywalkInterface->stop(this);
|
||||
fSkywalkInterface->detach(this);
|
||||
OSSafeReleaseNULL(fSkywalkInterface);
|
||||
}
|
||||
|
||||
IOWorkLoop *workLoop = getWorkLoop();
|
||||
if (fInterruptSource) {
|
||||
fInterruptSource->disable();
|
||||
|
||||
@@ -188,6 +188,7 @@ private:
|
||||
IOWorkLoop *fWorkLoop;
|
||||
IO80211WorkQueue *fWorkQueue;
|
||||
IONetworkInterface *fNetif;
|
||||
IO80211SkywalkInterface *fSkywalkInterface;
|
||||
IOEthernetAddress fMacAddress;
|
||||
|
||||
// État réseau Wi-Fi
|
||||
|
||||
@@ -17,11 +17,15 @@
|
||||
#error "Please define __IO80211_TARGET to the requested version"
|
||||
#endif
|
||||
|
||||
class IO80211SkywalkInterface : IOSkywalkEthernetInterface {
|
||||
class IO80211SkywalkInterface : public IOSkywalkEthernetInterface {
|
||||
OSDeclareAbstractStructors(IO80211SkywalkInterface)
|
||||
|
||||
public:
|
||||
|
||||
virtual bool init(IOService *controller, ether_addr *mac);
|
||||
virtual void setInterfaceRole(UInt32 role);
|
||||
virtual bool start(IOService *controller) APPLE_KEXT_OVERRIDE;
|
||||
virtual void stop(IOService *controller) APPLE_KEXT_OVERRIDE;
|
||||
virtual void free() APPLE_KEXT_OVERRIDE;
|
||||
};
|
||||
|
||||
#endif /* _IO80211SKYWALK_H */
|
||||
Reference in new issue
Block a user