如果静态编译的代码想要访问内核模块代码中的变量,那么模块是否必须静态编译?

时间:2012-09-19 14:36:57

标签: c linux module kernel

所以我相信内核模块代码可以使用静态编译的内核代码中的任何内容,只要它们被公开。但是如果静态编译的内核代码想要在模块代码中使用全局变量,那可能吗?

例如,我们在一个内核模块代码(无论可加载的内核模块)中有一个名为“int a”的全局变量。在静态编译的内核代码中(例如,在/linux/sched/fair.c中),我想访问该变量。

这将导致编译错误,因为模块最后编译(在编译静态编译的内核代码之后)并且在开始时没有加载。

如果我首先在静态编译的头文件中声明此变量怎么办?但是在加载模块之前,该变量将毫无意义。

谢谢,

2 个答案:

答案 0 :(得分:1)

我认为内核和任何模块都能够使用find_symbol(在kernel / module.c中定义)来发现内核中任何其他符号的地址或任何已加载的模块,静态编译或不编译。

答案 1 :(得分:1)

根据您的需要,可能有不同的解决方案。我假设您至少控制了静态链接的代码,并且可以根据需要进行更改。

方式1

如果静态链接的代码可以导出函数(类似set_my_good_var_ptr()),则动态加载的模块可以调用该函数将所需变量的地址传递给前者。

或许,静态链接的代码可能提供一个接口,动态加载的模块可以使用它来提供get / set回调,从而允许访问变量。

如果所有这些都不适合您的项目(例如,如果您无法更改动态加载的模块的代码),以下内容可能有所帮助,尽管我不认为这是一个好习惯。

方式2

注意提供加载变量的内核模块(例如,参见register_module_notifier()函数)。

请注意,在模块加载后将调用通知函数,但在调用 初始化函数之前

调用通知功能后,您可以使用kallsyms_lookup_name()kallsyms_on_each_symbol()获取所需变量的地址。

这需要在内核配置中设置CONFIG_KALLSYMSCONFIG_KALLSYMS_ALL。如果未设置这些选项中的一个或两个,它仍然可行但更难一些(例如,在模块的二进制文件中找到符号,获取符号所属的ELF部分的地址以及其中的偏移量并通过所有这对你的代码等。)

找到变量的地址后,静态链接的代码必须以某种方式确定何时可以实际使用变量(初始化时等)。如何做到这一点取决于所涉及的模块实际上做了什么,我不能给出任何建议。