简单的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);

相关推荐