zoukankan      html  css  js  c++  java
  • 设备驱动之一 最简单的可运行的scull模块

    linux设备驱动程序 第三版学习

    头文件scull.h

    /**********************************************
     * Author: lewiyon@hotmail.com
     * File name: scull.h
     * Description: define scull
     * Date: 2012-07-4
     *********************************************/
    #ifndef __SCULL_H
    #define __SCULL_H
    
    #include <linux/semaphore.h>
    #include <linux/cdev.h>
    #include <linux/fs.h>           /* register      */
    
    #ifndef SCULL_MAJOR
    #define SCULL_MAJOR     0
    #endif
    
    #ifndef SCULL_NR_DEVS
    #define SCULL_NR_DEVS   1
    #endif
    
    #ifndef SCULL_QUANTUM
    #define SCULL_QUANTUM   5000
    #endif
    
    #ifndef SCULL_QSET
    #define SCULL_QSET      1000
    #endif
    
    /*
     * parameters of module
     */
    int scull_major;
    int scull_quantum;
    int scull_qset;
    
    
    struct scull_qset {
        void **data;
        struct scull_qset *next;
    };
    
    /*
     * define scull_dev struct
     */
    struct scull_dev {
        struct scull_qset *data; /* point first child set */
        int quantum;             /* size of current set   */
        int qset;                /* size of array         */
        unsigned long size;      /* save total quantity   */
        unsigned int access_key; /* used by scullid and scullpriv */
        struct semaphore sem;    /* mutex                 */
        struct cdev cdev;        /* character device      */
    };
    
    struct file_operations scull_fops;
    
    int scull_trim(struct scull_dev *dev);
    
    #endif
    

    scull.h文件

    /**********************************************
     * Author: lewiyon@hotmail.com
     * File name: initialize and release function for scull
     * Description: scull
     * Date: 2012-07-4
     *********************************************/
    
    #include <linux/init.h>         /* module        */
    #include <linux/module.h>       /* module        */
    #include <linux/moduleparam.h>  /* module        */
    #include <linux/errno.h>        /* error codes   */
    #include <linux/kernel.h>       /* printk        */
    #include <linux/slab.h>         /* kmalloc kfree */
    #include <linux/types.h>        /* dev_t         */
    
    /* local head files */
    #include "scull.h"
    
    /* default parameters of module */
    int scull_major = SCULL_MAJOR;
    int scull_minor = 0;
    int scull_nr_devs = SCULL_NR_DEVS;
    int scull_quantum = SCULL_QUANTUM;
    int scull_qset = SCULL_QSET;
    
    /* input parameters of module */
    module_param(scull_major, int, S_IRUGO);
    module_param(scull_minor, int, S_IRUGO);
    module_param(scull_nr_devs, int, S_IRUGO);
    module_param(scull_quantum, int, S_IRUGO);
    module_param(scull_qset, int, S_IRUGO);
    
    struct scull_dev *scull_devices;
    
    /*
     * scull_trim -  遍历链表,并释放所有找到的量子和量子集
     */
    int scull_trim(struct scull_dev *dev)
    {
        int i, qset;
        struct scull_qset *next, *dptr;
        
        qset = dev->qset;
        for (dptr = dev->data; dptr; dptr = next) {
            if (dptr->data) {
                for (i = 0; i < qset; i++)
                    kfree(dptr->data[i]);
                kfree(dptr->data);
                dptr->data = NULL;
            }
            next = dptr->next;
            kfree(dptr);
        }
        dev->size = 0;
        dev->quantum = scull_quantum;
        dev->qset = scull_qset;
        dev->data = NULL;
    
        return 0;
    }
    
    static void scull_setup_cdev(struct scull_dev *dev, int index)
    {
        int err;
        int devno;
    
        devno = MKDEV(scull_major, scull_minor + index);
        cdev_init(&dev->cdev, &scull_fops);
        dev->cdev.owner = THIS_MODULE;
        //dev->cdev.ops = &scull_fops;
       
        err = cdev_add(&dev->cdev, devno, 1);
        if (err) 
            printk(KERN_NOTICE "Error %d adding scull%d", err, index);
        
    }
    
    /*
     * initialze scull module 
     */
    void scull_cleanup_module(void)
    {
        int i;
        dev_t devno;
    
        devno = MKDEV(scull_major, scull_minor);
        /* delete each entry */
        if (scull_devices) {
            for (i = 0; i < scull_nr_devs; i++) {
                scull_trim(scull_devices + i);
                cdev_del(&scull_devices[i].cdev);
            }
            kfree(scull_devices);
        }
    
        /* unregister */
        unregister_chrdev_region(devno, scull_nr_devs);
        printk(KERN_WARNING "scull: Bye!\n");
    }
    
    
    /*
     * initialze scull module 
     */
    int scull_init_module(void)
    {
        int i, res;
        dev_t dev = 0;
        
        if (scull_major) {
            dev = MKDEV(scull_major, scull_minor);
            res = register_chrdev_region(dev, scull_nr_devs, "scull");
        } else {
            res = alloc_chrdev_region(&dev, scull_minor, 
                    scull_nr_devs, "scull");
            scull_major = MAJOR(dev);
        }
        if (res < 0) {
            printk(KERN_WARNING "scull: can't get major %d\n", scull_major);
            return res;
        }
    
        /* 
         * allocate the device struct cache
         */
        scull_devices = kmalloc(scull_nr_devs * sizeof(struct scull_dev), 
                GFP_KERNEL);
        if (NULL == scull_devices) {
            res = -ENOMEM;
            printk(KERN_WARNING "scull: NOMEM for scull!\n");
            goto fail;
        }
        memset(scull_devices, 0, scull_nr_devs * sizeof(struct scull_dev));
        /* initialize each device */
        for (i = 0; i < scull_nr_devs; i++) {
            scull_devices[i].quantum = scull_quantum;
            scull_devices[i].qset = scull_qset;
            sema_init(&scull_devices[i].sem, 1);
            scull_setup_cdev(&scull_devices[i], i);
        }
        printk(KERN_INFO "scull: OK!\n");
        return 0;
    fail:
        scull_cleanup_module();
        return res;
    }
    
    module_init(scull_init_module);
    module_exit(scull_cleanup_module);
    
    MODULE_AUTHOR("lewiyon@hotmail.com");
    MODULE_LICENSE("GPL");

    makefile文件

    obj-m := scull.o 
    KERNELBUILD := /lib/modules/$(shell uname -r)/build
    default:
    	$(MAKE) -C $(KERNELBUILD) M=$(shell pwd) modules
    clean:
    	-rm -rf *.o .*.cmd *.ko* *.mod.c .tmp_versions
    	-rm -rf  modules.order Module.symvers

    make;然后安装模块



    ok~~~

  • 相关阅读:
    dp学习笔记1
    hdu 4474
    hdu 1158(很好的一道dp题)
    dp学习笔记3
    dp学习笔记2
    hdu 4520+hdu 4522+hdu 4524(3月24号Tencent)
    hdu 1025(最长非递减子序列的n*log(n)求法)
    hdu 2063+hdu 1083(最大匹配数)
    hdu 1023
    《 Elementary Methods in Number Theory 》Exercise 1.3.12
  • 原文地址:https://www.cnblogs.com/youngerchina/p/5624619.html
Copyright © 2011-2022 走看看