【问题标题】:Override Mac XNU kernel without recompiling source code在不重新编译源代码的情况下覆盖 Mac XNU 内核
【发布时间】:2013-12-31 16:10:50
【问题描述】:

我想在没有连接交流适配器的情况下以翻盖模式使用 Macbook air。但是,当我合上盖子时,Mac OS 会强制系统进入睡眠状态。

我发现苹果开源的这部分 XNU 内核可能与这种行为有关:

iokit/Kernel/IOPMrootDomain.cpp

...

6362     /*
6363      * Evaluate clamshell and SLEEP if appropiate
6364      */
6365     if (eval_clamshell && clamshellClosed)
6366     {
6367         if (shouldSleepOnClamshellClosed())
6368             privateSleepSystem (kIOPMSleepReasonClamshell);
6369         else
6370             evaluatePolicy( kStimulusDarkWakeEvaluate );
6371     }

...

3061 //******************************************************************************
3062 // sleepOnClamshellClosed
3063 //
3064 // contains the logic to determine if the system should sleep when the clamshell
3065 // is closed.
3066 //******************************************************************************
3067 
3068 bool IOPMrootDomain::shouldSleepOnClamshellClosed( void )
3069 {
3070     if (!clamshellExists)
3071         return false;
3072 
3073     DLOG("clamshell closed %d, disabled %d, desktopMode %d, ac %d sleepDisabled %d\n",
3074         clamshellClosed, clamshellDisabled, desktopMode, acAdaptorConnected, clamshellSleepDisabled);
3075 
3076     return ( !clamshellDisabled && !(desktopMode && acAdaptorConnected) && !clamshellSleepDisabled );
3077 }

当然,我可以编译内核,但我怀疑它是否是最新的 Mavericks 内核。所以我想知道我是否可以通过插入动态库来覆盖内核空间函数,就像我们为用户空间函数所做的那样。

【问题讨论】:

    标签: macos kernel xnu


    【解决方案1】:

    重新编译 xnu 内核比您想象的要容易:

    http://shantonu.blogspot.ca/2013/10/building-xnu-for-os-x-109-mavericks.html

    不过,Apple 为 OSX 的维护版本发布源代码的速度相当缓慢,因此您必须延迟更新 10.9.x,直到源代码可用为止。

    除此之外,您还有两个明显的选择:

    • 直接在磁盘上修补 mach_kernel 可执行文件。
    • 使用专门构建的 kext 在运行时修补 IOPMrootDomain::shouldSleepOnClamshellClosed 函数。

    在这两种情况下,请在 mach_kernel 反汇编中找到 IOPMrootDomain::shouldSleepOnClamshellClosed 函数。找出它在哪里读取 acAdaptorConnected 并将这些指令替换为使代码表现得好像 acAdaptorConnected 始终为真的指令。

    在运行时修补时需要小心。该方法是私有的,因此您无法使用 kext 链接器直接获取其地址,因此您需要从其他地方获取地址。

    FWIW,我不是 100% 相信此代码应归咎于您所看到的行为。如果连接了外部显示器,clamshellDisabled 通常应为true。如果您专门尝试使用带有 no 屏幕的 Macbook,您可以尝试生成一个虚假的 kIOPMDisableClamshell 电源事件,这应该会翻转该标志。

    顺便说一句,Apple 在内核中硬编码这种行为有点令人失望——这似乎是一个简单的用户空间脚本应该决定的事情。 :-(

    【讨论】:

    • 通读之后,如果出现外接显示器,您认为 clamshellDisabled 为 true 是正确的。这个周末我将尝试启用调试标志,看看是否能找到任何东西。我想内核可能已签名。选项 1 可能不起作用。我不确定如何准确地实现选项 2。所以我最终可能会编译内核。无论如何,感谢您的指导。我对快速反应感到非常惊讶。我相信这个功能在苹果笔记本电脑用户中很受欢迎。
    • mach_kernel 根本没有签名:codesign -v /mach_kernel 表示/mach_kernel: code object is not signed at all。所以修改/替换它是没有问题的。
    猜你喜欢
    • 2017-10-26
    • 1970-01-01
    • 2013-01-30
    • 1970-01-01
    • 2013-09-27
    • 1970-01-01
    • 2023-03-03
    • 2017-02-04
    • 1970-01-01
    相关资源
    最近更新 更多