2012-03-21 1 views
0

こんにちは私はキャラクタドライバ用のwrite()メソッドを書いています。なぜなら、ユーザのデータを自分のカーネルバッファにコピーして、バッファにランダムなジバリッシュが含まれているのはなぜだろうかと思いました。ベローは私が使っている方法です。カーネルバッファから文字列を出力するにはどうすればよいですか?私はcopy_from_user()を使用していますか?

ssize_t dev_write(struct file *filp, const char __user *buff, size_t count, loff_t *offp){// This function looks good 
    struct my_char_structure *my_dev = filp->private_data; 
    char *offset; // This points to my buffer 
    size_t np, left_to_print = count; // These are the bytes left to write 


//my_dev->set.write is a double pointer to a sentence where 
//set.write = array[sentence number][character in sentence] 
//set.write if set.write points to non-allocated memory, the sentence number is NULL 
//My device only holds 100 sentences in all 

    if(my_dev->set.write == NULL){// Write is a double pointer that points 
     printk(KERN_ALERT "Device has no more room"); 
     return -ENOMEM; // Look up 
    } 


//you can ignore the commented out stuff but I want to check to see if I'm referencing 
//a sentence that has been filled out. other wise the sentence is null and may be 
//written to. I will add this to my code later for traversing sentences. 
    /*if(*(my_dev->set.write) != NULL){ 
     my_dev->set.write ++; 
     dev_write(filp,buff,count,offp); 
     exit 0; 

    }*/ 

    if (down_interruptible(&my_dev->sem)) 
     return -ERESTARTSYS; 

// Here I'm referencing a memory segment that acts as a pointer to a sentence which 
//I write to. *(my_dev->set.write) is a pointer to a char buff which I will place chars 
// which is essentially my string 

    *(my_dev->set.write) = kmalloc(count,GFP_KERNEL); 
    offset = *(my_dev->set.write); // my offset points to that buffer as well 

//A sentence can only be the size of count, which is passed by the user 
//thats why I allocate count bytes for memory. 


     if((np = copy_from_user(offset,buff,left_to_print)) < 0) 
      goto erro_out; 

     left_to_print -= (count-np); 
     offset += (count-np); 
     offp += (count-np); 

//For debbuging purposes I have printk(). My offset points to my buffer, however 
//prints jibberish. In user space I insert \0 at the end of the string. 

      printk(KERN_ALERT " 4 :: write && left is ... %ld. The string %s", left_to_print, offset); // %s prints jibberish 

    return left_to_print; // change to count 

    erro_out:// if there was an error I free the sentence so that it may be written to. 

     kfree(*(my_dev->set.write)); 
     printk(KERN_ALERT "Print error %ld",np); 
     return -EFAULT; // look this up 
} 

私の方法がちょっと風変わりである場合、私の方法の概要を以下に示します。これは、デバイスへの初めての書き込みに適しているはずです。

ssize_t dev_write(struct file *filp, const char __user *buff, size_t count, loff_t *offp){// This function looks good 
    struct my_char_structure *my_dev = filp->private_data; 
    static char *offset; 

    if (down_interruptible(&my_dev->sem)) 
     return -ERESTARTSYS; 

    *(my_dev->set.write) = kmalloc(count,GFP_KERNEL); 
    offset = *(my_dev->set.write); 

     if(copy_from_user(offset,buff,left_to_print) < 0) 
      goto erro_out; 

// This is my question, why does %s print jibberish 

      printk(KERN_ALERT " 4 :: write && left is ... %ld. The string %s", left_to_print, offset); 

    return 0; // change to count 

    erro_out: 
     kfree(*(my_dev->set.write)); 
     printk(KERN_ALERT "Print error %ld",np); 
     return -EFAULT; // look this up  
} 

echo "my sentence">/dev/my_devを使用してデバイスに書き込みます。エコーがうまくいくかどうかは気にしない。私はprintk()が "my sentence"を表示して、copy_fromが動作していることを意味します。また、私はエコー "私の文\ 0">/dev/my_devを使用して、文字列の最後にヌル文字を貼り付けるルールを守ろうとしました。

ありがとうございました。

答えて

3

copy_from_userの最初の引数には、宛先アドレスが必要です。このようにオフセットを渡すと:

if((np = copy_from_user(offset,buff,left_to_print)) < 0) 

書き込みに間違ったアドレスを指定しています。

if((np = copy_from_user(_my_buffer_ + offset,buff,left_to_print)) < 0) 

あなたはアドレスにoffsetを追加し、私はあなたのバッファがsizeofは1と評価されたデータ型であると仮定していますのでご注意できるように、十分なスペースを割り当てていることを確認してください:あなたは次のように、あなたのバッファを渡す必要があります。

+0

これを見ていただきありがとうございます。最初はoffset = start_of_bufferに設定しました。私はオフセットが本当に私のオフセットではなく、私の出発点であるという意味で誤解を招くと思います。私はテスト目的のためだけにしましたが、あなたが正しいので、それは私の元のコードではないので修正します。 –

+0

ok、 '' memset(offset、0、count) ''を実行すると、ガベージが表示されますか? – Fred

関連する問題