加载内核模块时未知的符号

时间:2020-06-10 16:51:58

标签: c linux ubuntu kernel-module

我试图重做本主题How can I obtain battery level inside a Linux kernel module?中找到的内核模块代码。但是,当我尝试使用power_supply.h头文件中包含的功能时,该模块的加载失败,因为它无法识别power_supply_get_by_name函数。

这是我在内核版本为4.15.0-101-generic的Ubuntu 18.04上使用的代码:

#include <linux/module.h>
#include <linux/power_supply.h>

static int __init test_init (void)
{
        struct power_supply *psy;
        char name[] = "BAT1";

        psy = power_supply_get_by_name(name);

        printk(KERN_DEBUG "Test module inserted");

        return 0;
}

static void __exit test_exit (void)
{
        printk(KERN_DEBUG "Test module removed");
}

module_init (test_init);
module_exit (test_exit);

除了关于模块许可证的警告外,我在编译时没有任何错误,我认为这与我的问题无关,但出现以下错误:

  1. 在终端中运行insmod时:“ insmod:错误:无法插入模块test.ko:模块中的未知符号”
  2. 在/var/log/kern.log文件中:“测试:未知符号power_supply_get_by_name(err 0)”

我检查了kallsyms proc文件,并且如果我对主题What is the difference between T and t in /proc/kallsyms的理解很好,则该函数在其他内核模块中可用。这是读取kallsyms文件的输出:

ffffffff8e9bd270 T power_supply_get_by_name

有人知道为什么这不起作用,而我可以使用其他linux标头函数时没有任何问题,如果可以的话,如何解决我的问题?

预先感谢

1 个答案:

答案 0 :(得分:1)

这实际上可能与模块许可证有关!如果您查看内核源代码,则功能power_supply_get_by_name将被导出here。您可以看到它正在使用EXPORT_SYMBOL_GPL。正如this answer所解释的:

EXPORT_SYMBOL_GPL仅在GPL许可的模块中显示该符号

使用此宏有争议,但这是项目运行的方式...要获得所需符号的访问权限,您需要将模块许可为GPL:

MODULE_LICENSE("GPL");