加载自己的内核模块时出现未知符号

4
下面的代码(大部分摘自这里)是一个非常简单的内核模块,它作为键盘记录器。我可以成功编译并生成.ko文件,但当我尝试加载它时,在dmesg中会出现以下错误:
[  790.833828] keylogger: Unknown symbol unregister_keyboard_notifier (err 0)
[  790.833846] keylogger: Unknown symbol register_keyboard_notifier (err 0)

我没有从源代码构建我的内核,而是使用了archlinux提供的现成内核。但我安装了kernel-headers包来编译模块。
因此我的问题是:这两个符号在我的安装的内核中真的不存在吗?如果存在,为什么它们不能正确链接(?)?
我可以找到这些符号的证据。首先,我可以在/proc/kallsyms中看到这些符号。另外,当我运行nm /usr/src/vmlinux时,我也可以看到这两个符号。它们不是相同的吗?
模块代码:
#include <linux/module.h>   /* Needed by all modules */
#include <linux/keyboard.h>

EXPORT_SYMBOL_NOVERS(unregister_keyboard_notifier);
EXPORT_SYMBOL_NOVERS(register_keyboard_notifier);

int hello_notify(struct notifier_block *nblock, unsigned long code, void *_param) {
    struct keyboard_notifier_param *param = _param;
    struct vc_data *vc = param->vc;

    int ret = NOTIFY_OK;

    if (code == KBD_KEYCODE) {
        printk(KERN_DEBUG "KEYLOGGER %i %s\n", param->value, (param->down ? "down" : "up"));
    }
}

static struct notifier_block nb = {
    .notifier_call = hello_notify
};

static int hello_init(void)
{
    register_keyboard_notifier(&nb);
    return 0;
}

static void hello_release(void)
{
    unregister_keyboard_notifier(&nb);
}

module_init(hello_init);
module_exit(hello_release);
1个回答

4

我需要在我的模块源代码中添加以下内容:

MODULE_LICENSE("GPL");

[讽刺] 很高兴内核源代码有很好的文档记录。[/讽刺] 至少我不是唯一一个遇到这个问题的人。你有没有发现为什么那一行代码会有所不同? - Will
我认为这行声明了该模块在GPL(或兼容的许可证)下被许可。法律上你不能将非GPL模块与GPL内核源代码进行链接。 - gdw2
啊,那就很有道理了。我有点想到这个推理,但不确定。 - Will

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接