首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >内核模块无法链接-找不到symbol mutex_lock_nested

内核模块无法链接-找不到symbol mutex_lock_nested
EN

Stack Overflow用户
提问于 2014-09-25 21:01:55
回答 1查看 1.2K关注 0票数 0

我正在尝试为x64上的Linux3.10.45构建一个内核模块(硬件的压力测试工具)。

我使用和函数mutex_init、mutex_lock、mutex_unlock和mutex_destroy添加了互斥。

构建模块时没有产生任何错误或警告,但是当使用'insmod‘加载时,dmesg中会出现错误消息:

代码语言:javascript
复制
[76603.744551] tryBlk: Unknown symbol mutex_lock_nested (err 0)
[76603.744574] tryBlk: Unknown symbol mutex_destroy (err 0)

我发现一个提示,对于‘未知符号’,添加MODULE_LICENSE("GPL v2")行有时会有帮助。

没什么区别。

查看linux/mutex.h,我发现只有在定义了符号CONFIG_DEBUG_LOCK_ALLOC的情况下,mutex_lock才会定义为mutex_lock_nested。(我不记得摸过它。

这有什么问题吗?我是否需要手动向我的模块添加其他东西,以使其使用此调试功能进行构建?

已尝试更改包含文件和顺序。没什么区别。

系统正在运行Debian-7 'Wheezy‘x64,内核改为3.10.45。

使用互斥锁的文件:

代码语言:javascript
复制
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/mutex.h>
#include <linux/vmalloc.h>
#include <linux/uaccess.h>
#include "ring.h"




struct RingBuf
{
    unsigned char *buffer;
    unsigned int size;
    unsigned int inp,outp;
    struct mutex mtx;
};



static int _bytesavail(struct RingBuf *self);
static int _spaceavail(struct RingBuf *self);


struct RingBuf *RingBuf_init(unsigned int size)
{
  struct RingBuf *self;
    if( size<16 )size=16;
    if( size>0x10000000u )return 0;
    if( size & (size-1) )
    {
      unsigned int ns;
        // is not a power of 2.
        size = size<<1;
        while(1)
        {
            ns=size&(size-1);
            if(!ns)break;
            size=ns;
        }
    }
    self = (struct RingBuf*)vmalloc(sizeof(*self)+size);
    memset( self , 0 , sizeof(*self) );
    self->buffer = (unsigned char*)(self+1);
    self->size = size;
    self->inp = 0;
    self->outp = 0;
    mutex_init( &(self->mtx) );
    return self;
}

void RingBuf_uninit(struct RingBuf *self)
{
    if(!self)return;
    mutex_lock( &(self->mtx) );
    mutex_destroy( &(self->mtx) );
    memset( self , 0xFE , sizeof(*self) );
    vfree(self);
}

int RingBuf_add(struct RingBuf *self,const void *data,int num)
{
  int cpy;
    if(num<=0)return 0;
    mutex_lock( &(self->mtx) );
    // check amount to copy
    cpy = _spaceavail(self);
    if(cpy>num)cpy=num;
    // one part or split
    if( self->inp+cpy <= self->size )
    {
        // one chunk
        memcpy( self->buffer+self->inp , data , cpy );
    }else{
      int p1 = (self->size-self->inp);
        // wrapped
        memcpy( self->buffer+self->inp , data , p1 );
        memcpy( self->buffer , ((const unsigned char*)data)+p1 , cpy-p1 );
    }
    self->inp = (self->inp+cpy) & (self->size-1) ;
    mutex_unlock( &(self->mtx) );
    return cpy;
}

int RingBuf_get(struct RingBuf *self,void *data,int num)
{
  int cpy;
    if(num<=0)return 0;
    mutex_lock( &(self->mtx) );
    // check amount to copy
    cpy = _bytesavail(self);
    if(cpy>num)cpy=num;
    // one part or split
    if( self->outp+cpy <= self->size )
    {
        // one chunk
        memcpy( data , self->buffer+self->outp , cpy );
    }else{
      int p1 = (self->size-self->outp);
        // wrapped
        memcpy( data , self->buffer+self->outp , p1 );
        memcpy( ((unsigned char*)data)+p1 , self->buffer , cpy-p1 );
    }
    self->outp = (self->outp+cpy) & (self->size-1) ;
    mutex_unlock( &(self->mtx) );
    return cpy;
}

int RingBuf_get_user(struct RingBuf *self,void __user *data,int num)
{
  int cpy;
  int ret;
    if(num<=0)return 0;
    mutex_lock( &(self->mtx) );
    // check amount to copy
    cpy = _bytesavail(self);
    if(cpy>num)cpy=num;
    // one part or split
    if( self->outp+cpy <= self->size )
    {
        // one chunk
        ret = copy_to_user( data , self->buffer+self->outp , cpy );
    }else{
      int p1 = (self->size-self->outp);
        // wrapped
        ret = copy_to_user( data , self->buffer+self->outp , p1 );
        if(!ret)
            ret = copy_to_user( ((unsigned char*)data)+p1 , self->buffer , cpy-p1 );
    }
    if(ret)return -1;
    self->outp = (self->outp+cpy) & (self->size-1) ;
    mutex_unlock( &(self->mtx) );
    return cpy;
}

int RingBuf_numBytes(struct RingBuf *self)
{
  int result;
    mutex_lock( &(self->mtx) );
    result = _bytesavail(self);
    mutex_unlock( &(self->mtx) );
    return result;
}

static int _bytesavail(struct RingBuf *self)
{
    return (self->inp-self->outp)&(self->size-1);
}

static int _spaceavail(struct RingBuf *self)
{
    return (self->outp-self->inp-1)&(self->size-1);
}
EN

回答 1

Stack Overflow用户

发布于 2014-09-25 23:51:10

我只是发现它在某种程度上取决于我是如何构建模块的。

互斥锁的东西在另一个源文件中(上面列出的那个)。当我将其剪切/粘贴到模块的第一个主源代码中时,它可以正常工作。

因此,如何创建跨越多个源文件的模块是一个问题。

我的(不能正常工作的) Makefile是:

代码语言:javascript
复制
obj-m += tryBlk.o
tryBlk-objs := ring.o

它在没有警告的情况下构建,但是没有正确地找到'ring.o‘文件中的内核符号。

===============================================

现在我也解决了另一个问题。要共享,makefile是错误的。

下面是更好的makefile:

代码语言:javascript
复制
obj-m := tryBlk.o
tryBlk-objs := tryBlk_main.o ring.o

我还需要将主要部分从'tryBlk.c‘重命名为'tryBlk_main.c’。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26039351

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档