2014-09-25 139 views
0

我正在尝试为x64上的Linux 3.10.45构建内核模块(用于硬件的压力测试工具)。 到目前为止,它似乎工作正常,直到添加互斥。内核模块将不会链接 - 符号mutex_lock_nested未找到

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

构建模块产生任何错误或警告,但“insmod的”加载的时候,也有dmesg的错误信息:

[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。检查这个,它似乎是在我的.config中定义的。 (不记得去碰它,它基本上只是kernel.org的一个内核,已经建成了)。

这有问题吗?我是否需要手动添加其他内容到我的模块中,以便使用此调试功能构建它?

试图改变包含文件和序列。没有不同。

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

使用互斥的文件:

#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); 
} 

回答

0

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

互斥量的东西是在另一个源文件(上面列出的)。当我将它剪切/粘贴到模块的第一个主要来源时,它可以工作。

所以这是一个如何创建跨越多个源文件的模块的问题。

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

obj-m += tryBlk.o 
tryBlk-objs := ring.o 

它关掉了警告,但在“ring.o”文件中的内核符号不正确地找到。

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

我现在也解决了另一个问题。分享,makefile是坏的。

这里更好的Makefile:

obj-m := tryBlk.o 
tryBlk-objs := tryBlk_main.o ring.o 

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