首页 > 解决方案 > 安装内核模块时出现未知符号错误

问题描述

我正在做我的操作系统作业。作业要求我们编写和编译一个 linux 内核模块。我需要在 kernel/fork.c 中使用 _do_fork 来分叉一个进程。但是,当我尝试将模块安装到内核空间时,安装失败并显示以下错误消息:

ERROR: could not insert module program2.ko: Unknown symbol in module

内核空间中的消息是:

program2: Unknown symbol _do_fork (err 0)

这是我解决问题的尝试:我在 fork.c 的源代码中导出了符号“_do_fork”:

//fork.c
long _do_fork(unsigned long clone_flags,
          unsigned long stack_start,
          unsigned long stack_size,
          int __user *parent_tidptr,
          int __user *child_tidptr,
          unsigned long tls)
{
    (body of _do_fork function);
}
EXPORT_SYMBOL_GPL(_do_fork);//I also tried EXPORT_SYMBOL()

并重新编译内核:

/my_linux_source_path/$me make bzImage

并重新启动系统,并在 Module.symvers 中找到导出的符号:

0x00000000 _do_fork vmlinux EXPORT_SYMBOL_GPL

并使用 extern 在我自己的源文件中声明它:

//program2.c
MODULE_LICENSE("GPL");
extern long _do_fork (unsigned long clone_flags,
    unsigned long stack_start,  
    unsigned long stack_size,
    int __user *parent_tidptr,
    int __user *child_tidptr,
    unsigned long tls);

int my_exec(void){
    printk("iamhere");
    return 0;
}
int my_fork(void *argc){

    //set default sigaction for current process
    int i;
    struct k_sigaction *k_action = &current->sighand->action[0];
    for(i=0;i<_NSIG;i++){
        k_action->sa.sa_handler = SIG_DFL;
        k_action->sa.sa_flags = 0;
        k_action->sa.sa_restorer = NULL;
        sigemptyset(&k_action->sa.sa_mask);
        k_action++;
    }
    
    /* fork a process using do_fork */
    int pid;
    
    pid=_do_fork(SIGCHLD,(unsigned long)&my_exec,0,NULL,NULL,0);
    printk("%d",pid);
    /* execute a test program in child process */
    
    /* wait until child process terminates */
    
    return 0;
}
//program init and exit; module init and exit;
...



但是同样的错误仍然存​​在,我不知道原因。有人可以帮我吗?我使用的内核是Linux-4.10.14,gcc版本是(Ubuntu 5.4.0-6ubuntu1~16.04.10)5.4.0 20160609

标签: linuxlinux-kernelkernel-module

解决方案


我相信 _do_fork 已经暴露在 shed.h 中,只需将其放在模块的开头,它就会找到它。

#include <linux/shed.h>

如果分配是一个内核模块,我认为你不应该重新编译你的内核来完成它。


推荐阅读