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

问题描述 投票:0回答:1

我试图重做在本主题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头文件功能而没有任何问题,如果可以的话,如何解决我的问题?

提前感谢

c linux ubuntu kernel-module
1个回答
0
投票

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

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

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

MODULE_LICENSE("GPL");
© www.soinside.com 2019 - 2024. All rights reserved.