为了实现更好的封装和模块化,我决定将我的内核驱动程序拆分为2个(可能更多)模块,每个模块负责不同的功能。
但是,我仍然需要在这些模块之间共享一些数据+逻辑(即一个模块可以管理与用户空间的通信,而另一个模块可以将其用作中介),我想知道是否有& #39;任何简单的方法都可以。
例如,我想将一些API从一个模块发布到另一个模块,这是绝对可行的,因为这两个模块都在内核进程下运行,并且映射在相同地址空间的不同范围内。
问题是每个内核模块都有自己的符号表,并且为了发布API,需要某种加载器来修复寻址/指针等。它就像调用{{当与库动态链接时,来自用户空间的1}}和dlopen
,但是在内核空间中,每个库也具有状态(由其所有内部堆/全局参数的当前快照定义的状态)。
我的问题是这种方法是否有效并且在macOS领域得到了应对?
编辑,在下面的question中,它解释了实现我的目标的linux方式,也许你知道在macOS / XNU中等同于dlsym
和symbol_get
?
答案 0 :(得分:1)
看起来Linux方面已在评论中得到解答。
对于macOS kexts ,要使用的机制是OSBundleLibraries
and OSBundleCompatibleVersion
Info.plist properties. kext 导出符号必须设置OSBundleCompatibleVersion
属性。该值必须小于或等于CFBundleVersion
,并允许您对API进行版本化。
希望导入其他kext符号的kext必须在OSBundleLibraries
字典中列出导出 kext的包标识符,使用适当的版本号。
请注意,链接另一个kext会导入所有的公共符号,因此我强烈建议将所有符号设为默认隐藏并提供显式的导出文件。要执行此操作,请启用"默认情况下隐藏的符号"在Xcode目标设置中,创建一个新的.exp(或.exports)文件,并在"导出的符号文件"中声明它。设置。至少,您需要将_kmod_info
添加到此文件中。然后添加要导出的所有符号,每行一个。
C函数和全局变量需要以下划线为前缀,C ++函数和静态类成员变量需要以通常的方式进行修改。您可以使用*
作为(部分)通配符,例如,对于具有许多成员函数的C ++类,这有时很方便。如果需要引用,xnu源代码分发包含大量导出文件的示例。您可以使用nm
工具生成kext中所有符号的列表,然后您可以从中选择&选择;这样可以避免手动修改名称。
凯克斯不能循环相互依赖。一个人需要成为"库,"另一个"用户"那个图书馆。如果需要进行交互,则需要使用回调,虚函数等。
"图书馆" kext 必须安装在/ Library / Extensions(OS X 10.8或更早版本的/ System / Library / Extensions)中,否则库的用户将找不到它,可能即使是库kext已加载。如果你的用户" kext在其OSBundleRequired
属性中指定本地或网络引导可能需要它,它所依赖的库应该声明这些条件的相同或超集,或者它们可能没有被适当地预链接/ kextcached。
Apple确实也有少量documentation on designing kext libraries。