前提
- register_chrdevの代わりにcdev関数を利用
- Linuxカーネル2.6以降ではこの方が推奨らしい
- その他は前回の記事同様
メモ
コード
simple_device_driver3.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/uaccess.h> // copy_from_user
#include <linux/cdev.h> // cdev★
#define NODE_NAME "kuredev"
#define SUCCESS 0
MODULE_LICENSE("Dual BSD/GPL");
static int major_num = 0;
static unsigned char k_buf[1024];
static int data_size;
static int read_count = 0;
static int minor_num = 1;//★
static struct cdev kure_cdev;//★
static int kure_open(struct inode *inode, struct file *file){
printk("kure_open\n");
return SUCCESS;
}
static int kure_release(struct inode *inode, struct file *file){
printk("kure_release\n");
return SUCCESS;
}
static ssize_t kure_read(struct file *file, char __user *buf, size_t count, loff_t *f_pos){
printk("kure_read, count: %d, data_size: %d\n", count, data_size);
if(read_count){
return 0;
}
int len;
if(count > data_size){
len = data_size;
}else{
len = count;
}
printk("len: %d\n", len);
copy_to_user(buf, k_buf, len);
read_count++;
return len;
}
static ssize_t kure_write(struct file *file, char __user *buf, size_t count,loff_t *f_pos){
printk("kure_write, count = %d\n", count);
copy_from_user(k_buf, buf, count);
data_size = count;
return count;
}
struct file_operations kure_fops = {
.owner = THIS_MODULE,
.read = kure_read,
.write = kure_write,
.open = kure_open,
.release = kure_release
};
static int kure_init(void){
// major_num = register_chrdev(major_num, NODE_NAME, &kure_fops);
dev_t dev = MKDEV(major_num, 0);//★
alloc_chrdev_region(&dev, 0, minor_num, NODE_NAME);//★
major_num = MAJOR(dev);//★
cdev_init(&kure_cdev, &kure_fops);//★
kure_cdev.owner = THIS_MODULE;//★
cdev_add(&kure_cdev, MKDEV(major_num, 0), minor_num);//★
printk("kure_init\n");
return SUCCESS;
}
static void kure_exit(void){
// unregister_chrdev(major_num, NODE_NAME);
dev_t dev = MKDEV(major_num, 0);//★
cdev_del(&kure_cdev);//★
unregister_chrdev_region(dev, minor_num);//★
printk("kure_exit\n");
}
module_init(kure_init);
module_exit(kure_exit);
実行結果
前回と一緒