2014-09-25 99 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'

相關問題