こんにちは私はキャラクタドライバ用の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を使用して、文字列の最後にヌル文字を貼り付けるルールを守ろうとしました。
ありがとうございました。
これを見ていただきありがとうございます。最初はoffset = start_of_bufferに設定しました。私はオフセットが本当に私のオフセットではなく、私の出発点であるという意味で誤解を招くと思います。私はテスト目的のためだけにしましたが、あなたが正しいので、それは私の元のコードではないので修正します。 –
ok、 '' memset(offset、0、count) ''を実行すると、ガベージが表示されますか? – Fred