简单的Linux字符设备驱动
//---------------------------驱动程序的源程序---------------------------------
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
#define DATASIZE 1000
MODULE_LICENSE("GPL");
int hello_major = 250;
int hello_minor = 0;
int number_of_devices = 1;
char data[DATASIZE] = "\0";
struct cdev cdev;
dev_t dev = 0;
static int hello_open(struct inode *inode, struct file *file){
return 0;
}
static int hello_release(struct inode *inode, struct file *file){
return 0;
}
ssize_t hello_write(struct file *file, const char __user *buf, size_t count, loff_t *f_pos){
ssize_t ret = 0;
printk(KERN_DEBUG"Writing %d bytes\n", count);
if(count > DATASIZE) return -ENOMEM;
if(count < 0) return -EINVAL;
if(copy_from_user(data, buf, count)) {
ret = -EFAULT;
}
else {
data[DATASIZE]='\0';
printk(KERN_DEBUG"Received:---\n%s\n----\n", data);
ret = count;
}
return ret;
}
struct file_operations hello_fops = {
.owner = THIS_MODULE,
.open = hello_open,
.release = hello_release,
.write = hello_write
};
static void char_reg_setup_cdev(void){
int error, devno = MKDEV(hello_major, hello_minor);
cdev_init(&cdev, &hello_fops);
cdev.owner = THIS_MODULE;
cdev.ops = &hello_fops;
error = cdev_add(&cdev, devno, 1);
if(error){
printk(KERN_NOTICE"Error %d adding char_reg_setup_cdev", error);
}
}
static int __init hello_init(void){
int result;
dev = MKDEV(hello_major, hello_minor);
result = register_chrdev_region(dev, number_of_devices, "hello");
if(result){
printk(KERN_WARNING"hello: can't get major number %d\n", hello_major);
return result;
}
char_reg_setup_cdev();
return 0;
}
static void __exit hello_exit(void){
dev_t devno = MKDEV(hello_major, hello_minor);
cdev_del(&cdev);
unregister_chrdev_region(devno, number_of_devices);
}
module_init(hello_init);
module_exit(hello_exit);