2014-09-25 5 views
0

나는 64에 리눅스 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를 보면 mutex_lock은 심볼 CONFIG_DEBUG_LOCK_ALLOC이 정의되어 있으면 mutex_lock_nested로 정의된다는 것을 알았습니다. 이것을 확인하면 내 .config 파일에 정의 된 것 같습니다. (건드릴 수는 없지만 기본적으로 kernel.org의 커널입니다.)

문제가 있습니까? 이 디버그 기능으로 모듈을 만들려면 모듈에 다른 것을 수동으로 추가해야합니까?

포함 파일 및 시퀀스를 변경하려고 시도했습니다. 차이 없음. 커널이 3.10.45로 변경하여

시스템, 데비안 7 '위지'의 x64를 실행 중입니다.

뮤텍스를 사용하는 파일 :

#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

난 그냥 어떻게 든 모듈을 건물입니다 방법에 따라 다릅니다 것을 발견했다.

뮤텍스 항목은 다른 소스 파일 (위에 나열된 항목)에 있습니다. 모듈의 첫 번째 주 소스에 잘라내어 붙여 넣으면 작동합니다.

그래서 여러 소스 파일에 걸친 모듈을 만드는 방법의 문제입니다.

내 (제대로 작동하지 않는) 메이크 파일은 다음과 같습니다

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

그것은 경고없이 빌드하지만 'ring.o'파일의 커널 기호를 제대로 찾을 수 없습니다.

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

다른 문제도 해결했습니다. 공유하려면 메이크 파일이 좋지 않았습니다. 여기

더 나은 메이크 :

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

또한 'tryBlk_main.c'

에 'tryBlk.c'에서 주요 부분의 이름을 바꿀 필요