设备驱动之一 - 最简单的可运行的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~~~
posted on 2012-07-08 19:11 YoungerChina 阅读(415) 评论(0) 编辑 收藏 举报