在多个不同的内核模块(驱动程序)之间进行通信 [英] Communicating between multiple distinct kernel modules (drivers)

查看:541
本文介绍了在多个不同的内核模块(驱动程序)之间进行通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了获得更好的封装和模块化,我决定将内核驱动程序拆分为2个(可能更多)模块,每个模块负责不同的功能.

In order to achieve better encapsulation and modularity I've decided to split my kernel driver into 2 (can be more) modules where each is responsible for different functionality.

但是,我仍然想在这些模块之间共享一些数据和逻辑(即一个模块可以管理与用户空间的通信,而另一个模块用作中介),我想知道是否有任何简单的方法这样做的方式.

However, there are still some data+logic which I'd like to share between those modules (i.e. one module can manage the communication with user-space, while the other uses it as mediator) and I wonder if there's any easy way to do so.

例如,我想将一些API从一个模块发布到另一个模块,这是绝对可行的,因为两个模块都在内核进程下运行,并且映射在同一地址空间中的不同范围内.

For example, I'd like to publish some API from one module to another, which is absolutely doable since both modules are running under kernel process and are mapped in separated ranges in the same address space.

问题是每个内核模块都有自己的符号表,并且要发布API,需要某种类型的加载器来修复寻址/指针/等.这就像调用dlopen与用户库动态链接时,但在内核空间中,并且每个库也拥有状态(由其所有内部堆/全局参数的当前快照定义的状态).

The catch is that each kernel module has symbol table of its own, and in order to publish the API, some sort of loader is needed to fix the addressing/pointers/etc.. It's like calling dlopen and dlsym from user-space when dynamically linking with library, but in kernel space and where each library also possess state (the state defined by the current snapshot of all its inner heap/global parameters).

我的问题是,这种方法在macOS领域是否有效并得到支持?

My question is whether this approach is valid and accpeted in the realms of macOS?

编辑,在下面的问题中,解释了Linux方式实现我的目标,也许您知道macOS/XNU中与symbol_getsymbol_put等价的东西是什么?

EDIT, in the following question, it's explained the linux way of achieving my goal, Perhaps do you know what's the equivalent in macOS/XNU to symbol_get and symbol_put ?

推荐答案

看来Linux方面已经在评论中得到了答复.

It looks like the Linux side has already been answered in comments.

对于macOS kexts ,使用的机制是

For macOS kexts, the mechanism to use are the OSBundleLibraries and OSBundleCompatibleVersion Info.plist properties. The kext exporting symbols must have the OSBundleCompatibleVersion property set. This must be less than or equal to its CFBundleVersion and allows you to version your API.

希望导入其他kext符号的kext必须在OSBundleLibraries词典中列出 exporting kext的捆绑标识符,并带有适当的版本号.

The kext which wishes to import the other kext's symbols must list the exporting kext's bundle identifier in the OSBundleLibraries dictionary, with the appropriate version number.

请注意,与另一个kext链接将导入其所有 all 公共符号,因此,我强烈建议将所有符号默认设置为隐藏,并提供一个明确的导出文件.为此,请在Xcode目标设置中启用默认情况下隐藏的符号",创建一个新的.exp(或.exports)文件,然后在导出的符号文件"设置中进行声明.至少,您需要将_kmod_info添加到此文件.然后添加所有要导出的符号,每行添加一个.

Note that linking against another kext will import all of its public symbols, so I strongly recommend making all symbols default-hidden and providing an explicit exports file. To do this, enable "Symbols hidden by default" in the Xcode target settings, create a new .exp (or .exports) file, and declare it in the "Exported Symbols File" setting. At a minimum, you will need to add _kmod_info to this file. Then add all the symbols you wish to export, one on each line.

C函数和全局变量将需要加下划线作为前缀,C ++函数和静态类成员变量将需要以通常的方式进行修饰.您可以将*用作(部分)通配符,例如,对于具有很多成员函数的C ++类,有时这很方便.如果需要参考,xnu源代码分发包含大量导出文件示例.您可以使用nm工具生成kext中所有符号的列表,然后可以从中选择&选择;这样可以避免手动修改名称.

C functions and global variables will need to be prefixed with an underscore, C++ functions and static class member variables will need to be mangled in the usual way. You can use * as a (partial) wildcard, which is sometimes handy for C++ classes with a lot of member functions, for example. The xnu source distribution contains plenty of examples of exports files if you need a reference. You can use the nm tool to generate a list of all the symbols in your kext, from which you can then pick & choose; this saves you from manually mangling names.

Kexts不能相互依赖.一个需要成为该库的库",另一个需要成为该库的用户".如果他们需要互动,则需要使用回调,虚函数等.

Kexts can't circularly depend on one another. One will need to be the "library," the other the "user" of that library. If they need to interact, you will need to use callbacks, virtual functions, etc.

必须在/Library/Extensions(OS X 10.8或更早版本上的/System/Library/Extensions)中安装库"扩展程序 ,否则库用户将找不到它,即使已加载库kext也可能.如果您的用户" kext在其OSBundleRequired属性中指定本地或网络启动可能需要它,则它依赖的库应声明相同或相同的库.这些条件的超集,或者可能没有适当地对其进行预链接/kextcached.

The "library" kext must be installed in /Library/Extensions (/System/Library/Extensions on OS X 10.8 or earlier) or the user of the library will not find it, potentially even if the library kext is already loaded. If your "user" kext specifies in its OSBundleRequired property that it may be needed for local or network booting, the libraries it depends on should declare the same or a superset of those conditions, or they may not be appropriately prelinked/kextcached.

Apple确实有少量设计kext库的文档.

Apple does have a small amount of documentation on designing kext libraries too.

这篇关于在多个不同的内核模块(驱动程序)之间进行通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆