【问题标题】:Unknown symbol when loading a kernel module加载内核模块时出现未知符号
【发布时间】:2020-09-30 04:26:11
【问题描述】:

我尝试重做此主题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: ERROR: could not insert module test.ko: Unknown symbol in module”
  2. 在 /var/log/kern.log 文件中:“test: Unknown symbol 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】:

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

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

    这个宏的使用是有争议的,但这是项目的运作方式......要访问您需要的符号,您需要将您的模块许可为 GPL:

    MODULE_LICENSE("GPL");
    

    【讨论】:

    • 我今天早上尝试了您的解决方案,效果很好!我从来没有想过……感谢您快速准确的回答!
    猜你喜欢
    • 2012-02-26
    • 2012-11-08
    • 2021-11-28
    • 2012-12-21
    • 1970-01-01
    • 2014-01-19
    • 2012-08-06
    • 1970-01-01
    • 2017-03-31
    相关资源
    最近更新 更多