高级字符驱动llseek以及ioctl函数Word文档下载推荐.docx

上传人:b****2 文档编号:5791470 上传时间:2023-05-05 格式:DOCX 页数:23 大小:24.54KB
下载 相关 举报
高级字符驱动llseek以及ioctl函数Word文档下载推荐.docx_第1页
第1页 / 共23页
高级字符驱动llseek以及ioctl函数Word文档下载推荐.docx_第2页
第2页 / 共23页
高级字符驱动llseek以及ioctl函数Word文档下载推荐.docx_第3页
第3页 / 共23页
高级字符驱动llseek以及ioctl函数Word文档下载推荐.docx_第4页
第4页 / 共23页
高级字符驱动llseek以及ioctl函数Word文档下载推荐.docx_第5页
第5页 / 共23页
高级字符驱动llseek以及ioctl函数Word文档下载推荐.docx_第6页
第6页 / 共23页
高级字符驱动llseek以及ioctl函数Word文档下载推荐.docx_第7页
第7页 / 共23页
高级字符驱动llseek以及ioctl函数Word文档下载推荐.docx_第8页
第8页 / 共23页
高级字符驱动llseek以及ioctl函数Word文档下载推荐.docx_第9页
第9页 / 共23页
高级字符驱动llseek以及ioctl函数Word文档下载推荐.docx_第10页
第10页 / 共23页
高级字符驱动llseek以及ioctl函数Word文档下载推荐.docx_第11页
第11页 / 共23页
高级字符驱动llseek以及ioctl函数Word文档下载推荐.docx_第12页
第12页 / 共23页
高级字符驱动llseek以及ioctl函数Word文档下载推荐.docx_第13页
第13页 / 共23页
高级字符驱动llseek以及ioctl函数Word文档下载推荐.docx_第14页
第14页 / 共23页
高级字符驱动llseek以及ioctl函数Word文档下载推荐.docx_第15页
第15页 / 共23页
高级字符驱动llseek以及ioctl函数Word文档下载推荐.docx_第16页
第16页 / 共23页
高级字符驱动llseek以及ioctl函数Word文档下载推荐.docx_第17页
第17页 / 共23页
高级字符驱动llseek以及ioctl函数Word文档下载推荐.docx_第18页
第18页 / 共23页
高级字符驱动llseek以及ioctl函数Word文档下载推荐.docx_第19页
第19页 / 共23页
高级字符驱动llseek以及ioctl函数Word文档下载推荐.docx_第20页
第20页 / 共23页
亲,该文档总共23页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

高级字符驱动llseek以及ioctl函数Word文档下载推荐.docx

《高级字符驱动llseek以及ioctl函数Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《高级字符驱动llseek以及ioctl函数Word文档下载推荐.docx(23页珍藏版)》请在冰点文库上搜索。

高级字符驱动llseek以及ioctl函数Word文档下载推荐.docx

#include"

scull01.h"

#defineSCULL2_SIZE0x1000/*定义全局内存最大4K字节*/#defineMEM_CLEAR0X1/*清0全局内存*/

#defineSCULL2_MAJOR0/*定义为动态分配主设备号*/

staticintscull2_major=SCULL2_MAJOR;

intscull2_minor=0;

intscull2_nr_devs=SCULL_NR_DEVS;

//设备数量intscull2_quantum=SCULL_QUANTUM;

intscull2_qset=SCULL_QSET;

/*scull2结构体定义*/structscull2_qset{void**data;

structscull2_qset*next;

};

structscull2_dev{structscull2_qset*data;

/*指向quantumset*/intquantum;

 

/*当前quantum大小*/intqset;

/*当前结构中数组大小*/unsignedlongsize;

/*存储数据量大小*/unsignedintaccess_key;

/*被sculluid和scullpriv调用*/structsemaphoresem;

/*信号量声明*/structcdevcdev;

/*字符设备结构体*/};

/*

structsemaphore{

spinlock_tlock;

//自旋锁类型

unsignedintcount;

//信号量计数

structlist_headwait_list;

//双向链表结构等待队列,即当需要等待信号量时,调用进程把自己加入到等待队列中,然后进入睡眠状态.

};

*/

structscull2_dev*scull2_devices;

//设备结构体指针

//清空scull2设备内容;

必须调用与信号设备。

intscull2_trim(structscull2_dev*dev){

structscull2_qset*next,*dptr;

//声明两个指针指向下一个和前一个字符设备结构

intqset=dev->

qset;

//dev不为null

inti;

//采用循环结构清空结构体中原有数据内容

for(dptr=dev->

data;

dptr;

dptr=next){

if(dptr->

data){

for(i=0;

i<

qset;

i++)

kfree(dptr->

data[i]);

//依次对结构体中每个段清空

data);

//最后清除设备信息

dptr->

data=NULL;

}

next=dptr->

next;

//指向设备中下一个字符设备

kfree(dptr);

//释放当前设备

}

//运用默认数据,初始化结构体中内容

dev->

size=0;

quantum=scull2_quantum;

qset=scull2_qset;

return0;

#ifdefSCULL_DEBUG//提供调试用的相关接口,仅需要在进行调试时被执行内容相关函数

//对于/proc文件系统,该函数的功能是读取入口,提供相关调试信息

intscull2_read_procmem(char*buf,char**start,off_toffset,intcount,int*eof,void*data){

inti,j,len=0;

intlimit=count-80;

//设备打印长度不超过80

//scull2_nr_devs为设备数量

for(i=0;

i<

scull2_nr_devs&

&

len<

=limit;

i++){

structscull2_dev*d=&

scull2_devices[i];

structscull2_qset*qs=d->

if(down_interruptible(&

d->

sem))

return-ERESTARTSYS;

len+=sprintf(buf+len,"

\nDevice%i:

qset%i,q%i,sz%li\n"

i,d->

qset,d->

quantum,d->

size);

for(;

qs&

len<

=limit;

qs=qs->

next){

len+=sprintf(buf+len,"

itemat%p,qsetat%p\n"

qs,qs->

if(qs->

data&

!

qs->

next)

for(j=0;

j<

j++){

data[j])

%4i:

%8p\n"

j,qs->

data[j];

up(&

scull2_devices[i].sem);

*eof=1;

returnlen;

//通过以上函数,实现了文件队列(seq_file)的同时存在,而以前的read_procmem函数也同样可以执行

//下面是进行顺序迭代,根据设备的设备号进行简单的迭代

staticvoid*scull2_seq_start(structseq_file*s,loff_t*pos){

if(*pos>

=scull2_nr_devs)

returnNULL;

//如果偏移位大于设备总数,返回空。

returnscull2_devices+*pos;

staticvoid*scull2_seq_next(structseq_file*s,void*v,loff_t*pos){

(*pos)++;

returnscull2_devices+*pos;

staticvoidscull2_seq_stop(structseq_file*s,void*v){//什么事也不用做}

//显示结构中相关信息。

staticintscull2_seq_show(structseq_file*s,void*v){structscull2_dev*dev=(structscull2_dev*)v;

structscull2_qset*d;

inti;

if(down_interruptible(&

sem)) 

return-ERESTRATSYS;

seq_printf(s,"

\nDevice%i:

qest%i,q%i,sz%li\n"

(int)(dev-scull2_devices),dev->

qset,dev->

quantum,dev->

for(d=dev->

d;

d=d->

next){ 

d,d->

if(d->

next) 

for(i=0;

i++){ 

data[i]) 

i,d->

 

}}up(&

sem);

return0;

//构建队列执行对应的结构体

staticstructseq_operationsscull2_seq_ops={

.start=scull2_seq_start,.next=sucll2_seq_next,.stop=scull2_seq_stop,.show=scull2_seq_show,};

//现在可以执行在/proc文件,我们只需要open,建立执行队列

staticintscull2_proc_open(structinode*inode,structfile*file){

returnseq_open(file,&

scull2_seq_ops);

//为/proc建立相关文件结构

staticstructfile_operationssucll_proc_ops={

.owner=THIS_MODULE,

.open=scull2_proc_open,

.read=seq_read,

.llseek=seq_lseek,

.release=seq_release,

//建立/proc执行的create及remove对应函数

staticvoidscull2_create_proc(void){

structproc_dir_entry*entry;

//create_proc_read_entry(名字,defaultmode,parentdir,调用函数,clientdata)

create_proc_read_entry("

scullmem"

0,NULL,scull2_read_procmem,NULL);

entry=create_proc_entry("

scullseq"

0,NULL);

if(entry)

entry->

proc_fops=&

scull2_proc_ops;

staticvoidscull2_remove_proc(void){

/*noproblemifitwasnotregistered*/

remove_proc_entry("

NULL/*parentdir*/);

NULL);

#endif//SCULL_DEBUG结束

//文件打开函数

intscull2_open(structinode*inode,structfile*filp){

structscull2_dev*dev;

//设备相关信息

dev=container_of(inode->

i_cdev,structscull2_dev,cdev);

//为其它方法forothermethods

filp->

private_data=dev;

//修改设备打开时为只写nowtrimto0thelengthofthedeviceifopenwaswrite-only

if(((filp->

f_flags&

O_ACCMODE)&

O_WRONLY)){ 

scull2_trim(dev);

//忽略errors

//文件释放函数

intscull2_release(structinode*inode,structfile*filp){

//顺序链表Followthelist

structscull2_qset*scull2_follow(structscull2_dev*dev,intn){

structscull2_qset*qs=dev->

//在首次调用或需要,为qset分配空间.Allocatefirstqsetexplicitlyifneedbe

if(!

qs){

qs=dev->

data=kmalloc(sizeof(structscull2_qset),GFP_KERNEL);

if(qs==NULL)

memset(qs,0,sizeof(structscull2_qset));

//顺序链表Thenfollowthelist

while(n--){

if(!

qs->

next=kmalloc(sizeof(structscull2_qset),GFP_KERNEL);

next==NULL)

memset(qs->

next,0,sizeof(structscull2_qset));

continue;

returnqs;

//ioctl设备控制函数

staticintscull2_ioctl(structinode*inode,structfile*filp,unsignedintcmd,unsignedlongarg){

interr=0,tmp;

intretval=0;

//从传递的cmd中提取出type和nr并作判断,但不执行解码

//如果不是定义的格式,则返回-ENOTTY

if(_IOC_TYPE(cmd)!

=SCULL_IOC_MAGIC)

return-ENOTTY;

if(_IOC_NR(cmd)>

SCULL_IOC_MAXNR)

//

if(_IOC_DIR(cmd)&

_IOC_READ)

err=!

access_ok(VERIFY_WRITE,(void__user*)arg,_IOC_SIZE(cmd));

elseif(_IOC_DIR(cmd)&

_IOC_WRITE)

access_ok(VERIFY_READ,(void__user*)arg,_IOC_SIZE(cmd));

if(err)

return-EFAULT;

switch(cmd){

caseSCULL_IOCRESET:

//设置为初始值

scull2_quantum=SCULL_QUANTUM;

scull2_qset=SCULL_QSET;

break;

caseSCULL_IOCSQUANTUM:

//传递arg值至scull2_quantum

capable(CAP_SYS_ADMIN))

return-EPERM;

retval=__get_user(scull2_quantum,(int__user*)arg);

caseSCULL_IOCTQUANTUM:

/*Tell:

argisthevalue*/

scull2_quantum=arg;

caseSCULL_IOCGQUANTUM:

//返回当前值Get:

argispointertoresult

retval=__put_user(scull2_quantum,(int__user*)arg);

caseSCULL_IOCQQUANTUM:

//返回positive

returnscull2_quantum;

caseSCULL_IOCXQUANTUM:

//交换,将传递的arg作为指针

tmp=scull2_quantum;

if(retval==0)

retval=__put_user(tmp,(int__user*)arg);

caseSCULL_IOCHQUANTUM:

/*shift:

likeTell+Query*/

returntmp;

caseSCULL_IOCSQSET:

retval=__get_user(scull2_qset,(int__user*)arg);

caseSCULL_IOCTQSET:

scull2_qset=arg;

caseSCULL_IOCGQSET:

retval=__put_user(scull2_qset,(int__user*)arg);

caseSCULL_IOCQQSET:

returnscull2_qset;

caseSCULL_IOCXQSET:

tmp=scull2_qset;

retval=put_user(tmp,(int__user*)arg);

caseSCULL_IOCHQSET:

/*

*Thefollowingtwochangethebuffersizeforscullpipe.

*Thescullpipedeviceusesthissameioctlmethod,justto

*writelesscode.Actually,it'

sthesamedriver,isn'

tit?

*/

#if0

caseSCULL_P_IOCTSIZE:

scull2_p_buffer=arg;

caseSCULL_P_IOCQSIZE:

returnscull2_p_buffer;

#endif 

default:

}returnretval;

//seek文件定位函数

staticloff_tscull2_llseek(structfile*filp,loff_toff,intwhence){structscull2_dev*dev=filp->

private_data;

loff_tnewpos;

switch(whence){ 

case0:

//SEEK_SET 

newpos=off;

case1:

//SEEK_CUR 

ne

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2