キャラクタデバイス "/ dev/coffee_bean"に書き込むシンプルなキャラクタドライバを作成しています。読み込み時に "Hi There!"という文字列が表示されます。コンソールで私は "cat/dev/coffee_bean"経由でデバイスから読み込み、代わりにシステムがクラッシュしてリセットします。ベローが私のソースコードです。手伝ってくれてありがとう。シンプルなキャラクタドライバのクラッシュ
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/kdev_t.h>
#include <linux/types.h>
#include <linux/completion.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
#include <linux/semaphore.h>
MODULE_LICENSE("Dual BSD/GPL");
#define DEVICE_NAME "coffee_grinds"
#define COUNT 4
#define FIRST_MINOR 0
#define CONST_QUANTUM 4000
#define CONST_QSET 4000
int test;
module_param(test, int, S_IRUGO);
struct my_char_structure{
struct cdev my_cdev;
struct semaphore sem;
unsigned int access_key;
unsigned long size;
};
static dev_t dev_num;
int dev_open(struct inode *in_node, struct file *filp){
struct my_char_structure *my_dev;
my_dev = container_of(in_node->i_cdev, struct my_char_structure, my_cdev);
filp->private_data = my_dev;
return 0;
}
int dev_release(struct inode *inode, struct file *filp){
return 0;
}
ssize_t dev_write(struct file *filp, const char __user *buff, size_t count, loff_t *offp){
struct my_char_structure *my_dev = filp->private_data;
ssize_t retval = -ENOMEM; /* value used in "goto out" statements */
char *my_string;
int counting;
printk(KERN_ALERT "Write was accessed, Lol");
if (down_interruptible(&my_dev->sem))
return -ERESTARTSYS;
my_string = kmalloc(count,GFP_KERNEL);
counting = copy_from_user(my_string,buff,count);
printk(KERN_ALERT "You wrote %s",my_string);
kfree(my_string);
up(&my_dev->sem);
printk(KERN_ALERT "We wrote %d bytes",counting);
return retval;
// Here is some experimental code
}
ssize_t dev_read(struct file *filp, char __user *buff, size_t count, loff_t *offp){
struct my_char_structure *my_dev = filp->private_data;
ssize_t retval = 0;
char *my_string;
printk(KERN_ALERT "Read was accessed Lol");
if (down_interruptible(&my_dev->sem))
return -ERESTARTSYS;
my_string = "Hi there!";
copy_to_user(buff,my_string,10);
up(&my_dev->sem);
return retval;
}
struct file_operations fops = {
.owner = THIS_MODULE,
.read = dev_read,
.write = dev_write,
.open = dev_open,
.release= dev_release,
};
int start_mod(void){
//Because we are dealing with a fictitious device, I want
//the driver to create my two devices with arbitrarly
//assigned major numbers.
static struct my_char_structure Dev;
static struct my_char_structure *my_dev = &Dev;
int err;
alloc_chrdev_region(&dev_num, FIRST_MINOR, COUNT, DEVICE_NAME);
sema_init(&(my_dev->sem),1);
cdev_init(&(my_dev->my_cdev), &fops);
my_dev->my_cdev.owner = THIS_MODULE;
my_dev->my_cdev.ops = &fops;// fops is my file operations struct
err = cdev_add(&my_dev->my_cdev, dev_num, COUNT);
if(err)
printk(KERN_ALERT "There was an error %d.",err);
printk(KERN_ALERT " insmod to major number %d",MAJOR(dev_num));
return 0;
}
void end_mod(void){
unregister_chrdev_region(dev_num, COUNT);
}
module_init(start_mod);
module_exit(end_mod);
Kazさん、ありがとうございました。プログラムをデバッグしましたが、クラッシュは自分の文字列にメモリを割り当てた方法によるものです。デバイスはもはやクラッシュしませんが、代わりにcopy_to_user()関数からのセグメンテーション違反が発生します。私は渡されたカウント変数を使用していないので、私はその欠陥があると思う。私のコードを見る時間をとってくれたバンドルありがとう! –
しかし、書き込みルーチンに割り当てがあります。あなたはそれが読んでクラッシュしていると言った。書き込みルーチンの主な問題は、 'kmalloc'はブロックがどれくらい返ってくるかに非常に制限があることです。物理的に連続したページ(貴重なリソース)を返します。しかし、「読み込み」の議論は非常に大きくなる可能性があります。私。一般に、ユーザ空間からの値を 'kmalloc'サイズ(それが何をしているのかを知っているルート特権サーバプログラム以外のもの)を使うことは良い考えではありません。たくさんのメモリがあってもヌルリターンの準備をしてください。 – Kaz
さて、私は "Hi There"のような小さなものをプリントアウトし、バイトをkmallocに割り当ててクラッシュからそれを止めたいだけです。今私は完全に機能するドライバを書くことを実装するために探しているわけではありません。私はちょうど最初に働くように読むことを望みます。これは私の最初のドライバで、読み書きを実装したものです。私は2週間前に勉強を始めました。 –