【问题标题】:If the statically compiled code wants to access a variable in the kernel module code, must the module be compiled statically?如果静态编译的代码要访问内核模块代码中的一个变量,模块必须要静态编译吗?
【发布时间】:2012-09-19 14:36:57
【问题描述】:

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

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

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

如果我首先在静态编译的头文件中声明这个变量会怎样?但是在加载模块之前,那个变量是没有意义的。

谢谢,

【问题讨论】:

  • 请添加一些代码或使问题更清楚。

标签: c linux module kernel


【解决方案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 部分的地址和其中的偏移量并传递所有这到您的代码等)

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2015-12-16
      • 2015-09-27
      • 1970-01-01
      • 2015-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-17
      • 1970-01-01
      相关资源
      最近更新 更多