在macOS

时间:2017-12-03 09:23:40

标签: c++ power-management iokit kernel-extension xnu

我希望我的IOKit驱动程序能够收到有关power offrestart事件的通知。幸运的是,IOKit使用IOService::systemWillShutDown方法提供此类通知,该方法应该被覆盖并包含我的逻辑。

以下是Apple Technical Documentation的示例:

void MyExampleDriver::systemWillShutdown( IOOptionBits specifier )
{ 
    if ( kIOMessageSystemWillPowerOff == specifier ) {
        // System is shutting down; perform appropriate processing.
    } else if ( kIOMessageSystemWillRestart == specifier ) {
        // System is restarting; perform appropriate processing.
    }
    /*
     * You must call your superclass's implementation of systemWillShutdown as
     * soon as you're finished processing your shutdown or restart
     * because the shutdown will not proceed until you do.
     */
    super::systemWillShutdown( specifier );
}

但是,该事件并未按预期显示。

或许错过了电力平面阶段的注册(尽管没有明确说明从systemWillShutDown覆盖方法IOService的先决条件。)

PMinit();
provider->joinPMtree(this);
registerPowerDriver(this, myPowerStates, 3);

为了获得重启和断电的电源事件,是否必须加入PMTree?

在尝试调试问题时,我已经在方法IOService::systemWillShutdown中设置断点,并且在关闭时确实会多次使用以下回溯调用:

frame #0: 0xffffff80134b1b04 kernel`IOService::systemWillShutdown(this=0xffffff801a0cf800, specifier=3758096976) at IOServicePM.cpp:7167 [opt]
frame #1: 0xffffff80135123f1 kernel`PMHaltWorker::work(me=<unavailable>) at IOPMrootDomain.cpp:8165 [opt]
frame #2: 0xffffff8013512178 kernel`PMHaltWorker::main(arg=<unavailable>, waitResult=<unavailable>) at IOPMrootDomain.cpp:8095 [opt]

所以似乎还有其他内核扩展可以接受此调用,它们列在gPMHaltArray中 - 但我的kext可能不在那里..

1 个答案:

答案 0 :(得分:0)

我认为 PMinit()调用是强制性的,如文档中所述:

  

要参与电源管理,以便您收到电源事件的通知,请确保驱动程序已正确连接到电源板上

https://developer.apple.com/library/archive/documentation/DeviceDrivers/Conceptual/IOKitFundamentals/PowerMgmt/PowerMgmt.html#//apple_ref/doc/uid/TP0000020-TPXREF104