2014-04-29 3 views
0

내가 사용 가짜 문자 장치 드라이버에 쓰기를 시도하고 안녕하세요 : 사용/이 가짜 문자 리눅스 디바이스 드라이버 작동하도록 도와주세요

에코>는/dev하고 읽기 :

cat/dev/

내 문제는 위의 echo 메서드를 사용하여 작성한 후에 위에서 언급 한 "cat"읽기 메서드를 사용하여 읽을 때 터미널에 인쇄 된 첫 번째 문자가 계속해서 나옵니다.

내 목표는

나는이 목적을 위해 동적 메모리 할당을 사용하지만의 코드를 재 작성의 여러 가지 방법을 시도한 후 최종 결과를 얻고 있지 않다 ... 다시 드라이버에 기록 된 문자의 전체 세트를 얻는 것입니다 드라이버의 read() 및 write(). 제발 도와주세요 ..

내 메이크 ...

내 코드는 다음과 같습니다 (나는 ... 2.6.33의 커널 버전의 우분투를 사용하고 있습니다) 올바른 :

#include <linux/module.h> 
#include <linux/version.h> 
#include <linux/kernel.h> 
#include <linux/types.h> 
#include <linux/kdev_t.h> 
#include <linux/fs.h> 
#include <linux/device.h> 
#include <linux/cdev.h> 
#include <linux/uaccess.h> 

static dev_t first; 
static struct cdev c_dev; 
static struct class *cl; 
static char* k_buf = NULL; 

static int my_open(struct inode *i,struct file *f) 
{ 
    printk(KERN_INFO "In driver open()\n"); 
    return 0; 
} 

static int my_close(struct inode *i,struct file *f) 
{ 
    printk(KERN_INFO "In driver close()\n"); 
    return 0; 
} 

static ssize_t my_read(struct file *f,char __user *buf,size_t len,loff_t *off) 
{ 
    printk(KERN_INFO "In driver read()\n"); 

    if(k_buf == NULL) 
    { 
     printk(KERN_INFO "You cannot read before writing!\n"); 
     return -1; 
    } 

    while(*k_buf != 'EOF') 
    { 
     if(copy_to_user(buf,k_buf,1)) 
      return -EFAULT; 
     off++; 
     return 1; 
    } 

    return 0; 
} 

static ssize_t my_write(struct file *f,const char __user *buf,size_t len,loff_t *off) 
{ 
    printk(KERN_INFO "In driver write()\n"); 
    k_buf = (char*) kmalloc(sizeof(len),GFP_KERNEL); 

    if(copy_from_user(k_buf,buf,len)) 
     return -EFAULT; 

    off += len; 

    return (len); 
} 

static struct file_operations fops = 
{ 
    .owner = THIS_MODULE, 
    .open = my_open, 
    .release = my_close, 
    .read = my_read, 
    .write = my_write 
}; 

static int __init rw_init(void) /*Constructor*/ 
{ 
    printk(KERN_INFO "hello: rw_ch_driver registered\n"); 

    if(alloc_chrdev_region(&first,0,1,"krishna") < 0) 
    { 
     return -1; 
    } 

    if ((cl = class_create(THIS_MODULE,"chardev")) == NULL) 
    { 
     unregister_chrdev_region(first,1); 
     return -1; 
    } 

    if (device_create(cl,NULL,first,NULL,"rw_char_driver") == NULL) 
    { 
     class_destroy(cl); 
     unregister_chrdev_region(first,1); 
     return -1; 
    } 

    cdev_init(&c_dev,&fops); 

    if(cdev_add(&c_dev,first,1) == -1) 
    { 
     device_destroy(cl,first); 
     class_destroy(cl); 
     unregister_chrdev_region(first,1); 
     return -1; 
    } 

return 0; 
} 

static void __exit rw_exit(void)/*destructor*/ 
{ 
    cdev_del(&c_dev); 
    device_destroy(cl,first); 
    class_destroy(cl); 
    unregister_chrdev_region(first,1); 
    printk(KERN_INFO "bye rw_chardriver unregistered"); 
} 

module_init(rw_init); 
module_exit(rw_exit); 
MODULE_LICENSE("GPL"); 
MODULE_AUTHOR("krishna"); 
MODULE_DESCRIPTION("read write character driver"); 

답변

0

테이크 my_read()에서 while 루프를주의 깊게 살펴보십시오.

가장 중요한 메모 먼저 :이 루프가 필요하지 않습니다. return 문을 넣었으므로 이 도달하면 전체 기능이 종료되므로 두 번 이상 실행하지 않습니다. 함수가 한 번에 한 바이트 씩 반환하도록하려는 것처럼 보입니다. 그러나 copy_to_user을 한 번 호출하고 대신 사용자에게 돌려 줄 바이트 수를 전달해야합니다. 한번에 한 글자 만 보내는다면 괜찮습니다. 다음 문자를 얻기 위해 다시 읽기 호출을하는 것은 사용자의 몫입니다.

copy_to_user의 좋은 점은 잘못된 배열 범위로 인해 실패한 경우 반환 코드가 알려주기 때문에 모든 문자에서 EOF를 확인할 필요가 없다는 것입니다. 사실 it doesn't exist이기 때문에 버퍼에서 읽을 때 'EOF'문자를 얻지 못할 것입니다. 버퍼에는 문자와 보통 '\ 0'이 저장되지만 C에는 'EOF'문자가 없습니다. EOF는 자신을 식별하고 open을 호출 한 사람에게보고해야하는 상태입니다. "cat"명령의 경우 읽기에서 0을 반환하여이 작업을 수행합니다. 즉, 배열 범위를 계속 확인하여 다른 Heartbleed으로 끝나지 않도록해야합니다. This SO answer에는 경계 검사를 수행하여 버퍼보다 ​​많은 바이트를 보내지 않는 방법에 대한 좋은 제안이 있습니다.

또한 [이 게시물 (https://meta.stackexchange.com/questions/981/syntax-highlighting-language-hints)을 읽으십시오. 질문 태그에 귀하의 언어가 없다면, 다른 독자가 귀하의 질문에 태그를다는 것이 도움이됩니다. 귀하의 질문을 편집하여 귀하의 질문을 정리했습니다. 그래서 지금 "편집"을 클릭하면 어떻게했는지 볼 수 있습니다.

관련 문제