一、前言
花了一整天时间整理下《linux设备驱动程序》第三章的例程和总结,还是要与实践相结合,才能学习到知识。
二、实例
开发环境介绍:使用Unbuntu12.0,内核使用2.6.35.3.
以下是所需的文件:
|scull.c|驱动主要实现方式|
|scull.h|定义结构体和函数|
|Makefile|编译模块 |
|scull_load.sh|加载模块脚本|
|scull_unload.sh|卸载模块脚本|
下面将列出所有源代码
1、scull.c
//#include <linux/config.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/fcntl.h>
#include <linux/seq_file.h>
#include <linux/cdev.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include "scull.h"
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;
module_param(scull_major,int,S_IRUGO);
module_param(scull_minor,int,S_IRUGO);
module_param(scull_nr_devs,int,S_IRUGO);
struct scull_dev *scull_devices;
/*empty out the scull device:must be called with the device semaphore held*/
/*scull_trim负责释放整个数据区,并且在文件以写入方式打开时由scull_open调用,它简单遍历链表,并且使用能找到的原子量*/
int scull_trim(struct scull_dev *dev)
{
struct scull_qset *next,*dptr;
int qset = dev->qset;
int i;
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;
}
/*若设备以读写方式打开,它的长度截零,未锁定信号量*/
int scull_open(struct inode *inode,struct file *filep)
{
struct scull_dev *dev;
dev = container_of(inode->i_cdev,struct scull_dev,cdev);
filep->private_data = dev;
if((filep->f_flags & O_ACCMODE) == O_WRONLY){
/*if(down_interruptible(&dev->sem))
* return -ERESTARTSYS;
* */
scull_trim(dev);
/*up(&dev->sem);*/
}
return 0;
}
int scull_release(struct inode *inode,struct file *filep)
{
return 0;
}
struct scull_qset *scull_follow(struct scull_dev *dev,int n)
{
struct scull_qset *qs = dev->data;
if(!qs){
qs = dev->data = kmalloc(sizeof(struct scull_qset),GFP_KERNEL);
if(qs == N