在早期启动过程中加载OS X kext

6
我有一个可用的OSX内核扩展,我希望它在开机时尽可能早地自动加载。该kext使用KAUTH监视特定路径上的访问,因此我认为不会有任何请求将其加载到内核中。在这种情况下,将其复制到/Library/Extensions(至少自Yosemite以来,这是第三方扩展的推荐路径)无法解决我的问题。
是否有可能实现这一点,无论是通过修改代码还是通过某些辅助配置?
我已经阅读了关于使用launchd守护程序使用kextload加载扩展的内容,如this question所述,但在我的情况下,我希望尽早加载它。

更新:
我正在使用一个“通用”的内核扩展(链接到BSD库),而不是基于I/O Kit的内核扩展。
我希望我的扩展在启动launchd之前被加载。


我也可以在安全启动模式下加载驱动程序,这得益于在“Info.plist”文件中设置的OsBundleRequired关键字。我目前正在使用“Root”,但我记得以前也使用过其他值。从文档中提到的值中选择最适合您的选项。 - MathPlayer
当你说“安全模式”时,你是指恢复模式吗?因为我发现当从恢复模式加载(在启动时按下command+R),我的kext甚至都找不到在/Library/Extensions中。 - Zohar81
我曾经错误地混淆了“安全启动”和“恢复模式”,它们似乎是两种不同的状态。 - Zohar81
似乎只要在 kext 中存在 OsBundleRequired 属性,就足以让其在安全启动模式下加载。 - MathPlayer
关于恢复模式,我认为你无法在那里编写你的kext,因为恢复分区被标记为只读。 - MathPlayer
显示剩余3条评论
2个回答

5
你在问题中没有明确说明,但我从上下文中推断出你正在使用“通用”内核扩展(与基于I/O Kit的内核扩展相对)。这些仅在其他内核扩展依赖它们或通过kextutil/kextload或KextManager API显式加载时才会被加载。
与此相反的是I/O Kit kexts,它们在其个性化字典与IO注册表中的已注册服务匹配时按需加载。这通常用于驱动特定设备,但各种非硬件相关的系统服务也使用该机制来匹配“IOResources”nub(documentation),它在早期引导期间出现,因此任何将其列为个性提供者的内核扩展也会在引导时加载。
因此,解决方案是修改您的内核扩展,以提供与IOResources nub匹配的IOService。如果您的用户空间组件已经使用另一个接口与内核扩展进行通信,则该服务本身实际上不需要执行任何操作。
如果您不想更改kext的代码本身,您可能可以创建一个虚拟kext来实现此功能,但是将您的主要kext声明为依赖项。后一种方法并不特别优雅,但是如果由于某种原因无法修改现有的kext,则应该可以工作。(尽管您可能需要修改info.plist)

是的,我正在尝试使用通用内核扩展而不是依赖于I/O Kit的扩展。我会更新问题。有趣的是,即使我制作了一个I/O Kit虚拟扩展,在Info.plist文件中列出我的通用kext作为依赖项,加载也是在启动launchd之后完成的,这与我想要实现的相反。 - MathPlayer
1
要让你的kext被添加到预链接内核中,你可以滥用OSBundleRequired属性。这告诉操作系统它是启动所必需的;通常由存储设备驱动程序等使用。有关详细信息,请参见https://developer.apple.com/library/mac/documentation/Darwin/Conceptual/KEXTConcept/Articles/infoplist_keys.html。 - pmdj
1
我知道OSBundleRequired属性。我通过将扩展名更改为基于I/O Kit的扩展名,并相应地设置所提到的属性来解决了我的问题。我在命名方面遇到了一些问题,似乎要求IOKitPersonality字典的名称与扩展名相同。 - MathPlayer
如果你指的是“bundle ID”,那么是的。 - pmdj

0

如果kext源自IOKit并驻留在/Library/Extensions中,请清除缓存,它将在启动时自动加载。您可以调用以下命令来清除缓存:

kextcache -f -update-volume /

@TheDarkNight,我已经尝试使用你提到的kextcache命令重建缓存,无论是在运行命令之前还是之后从/System/Library/Caches/com.apple.kext.caches中删除所有内容,都没有成功。 - MathPlayer
它是按照这种方式设计的。你是否检查了系统日志,看是否报告了有关加载您的 kext 的任何问题? - TheDarkKnight
只有基于I/O kit匹配的kext才能正常工作。我会写一篇单独的答案来详细解释。 - pmdj
4
请注意,Apple建议在生产环境中(安装脚本等)使用“touch /Library/Extensions/”命令(或者在10.9之前使用“touch /System/Library/Extensions/”)来触发内核缓存刷新。 - pmdj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接