scull源码分析 未完待续囧.docx

上传人:b****4 文档编号:11586189 上传时间:2023-03-19 格式:DOCX 页数:25 大小:26.42KB
下载 相关 举报
scull源码分析 未完待续囧.docx_第1页
第1页 / 共25页
scull源码分析 未完待续囧.docx_第2页
第2页 / 共25页
scull源码分析 未完待续囧.docx_第3页
第3页 / 共25页
scull源码分析 未完待续囧.docx_第4页
第4页 / 共25页
scull源码分析 未完待续囧.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

scull源码分析 未完待续囧.docx

《scull源码分析 未完待续囧.docx》由会员分享,可在线阅读,更多相关《scull源码分析 未完待续囧.docx(25页珍藏版)》请在冰豆网上搜索。

scull源码分析 未完待续囧.docx

scull源码分析未完待续囧

scull源码分析未完待续,囧

scull源码分析//未完待续,囧

 

Makefile

#disable/enabledebugging

#DEBUG=y#当DEBUG变量等于y时。

两个比较变量用括号括起来,逗号分隔。

ifeq和括号中间有一个空格。

ifeq($(DEBUG),y)

#+=追加变量值。

如果该变量之前没有被定义过,+=就自动变成=,变量被定义成递归展开式的变量;如果之前已经定义过,就遵循之前的风格。

#=递归展开式变量:

在定义时,变量中对其它变量的引用不会被替换展开。

变量在引用它的地方被替换展开时,变量中其它变量才被同时替换展开。

#-O程序优化参数;

#-g使生成的debuginfo包额外支持gnu和gdb调试程序,易于使用

#-DSCULL_DEBUG即defineSCULL_DEBUGTODO

DEBFLAGS+=-O-g-DSCULL_DEBUG#-Oisneededtoexpandinlines

else

DEBFLAGS+=-O2

endif#CFLAGS影响编译过程。

应在遵循原设置的基础上添加新的设置,注意+=

CFLAGS+=$(DEBFLAGS)

#-I选项指出头文件位置。

LDDINC是下面定义的一个变量。

CFLAGS+=-I$(LDDINC)#如果KERNELRELEASE不等于空。

ifneq判断参数是否不相等。

ifneq($(KERNELRELEASE),)

#:

=直接展开式变量:

在定义时就展开变量中对其它变量或函数的引用,定以后就成了需要定义的文本串。

不能实现对其后定义变量的引用。

scull-objs:

=main.opipe.oaccess.o

obj-m:

=scull.o

#否则(KERNELRELEASE是空)

else

#?

=条件赋值:

只有在此变量之前没有赋值的情况下才会被赋值。

#shellunamer内核版本号

KERNELDIR?

=/lib/modules/$(shellunamer)/build

#shellpwd当前在文件系统中的路径

PWD:

=$(shellpwd)

modules:

#$(MAKE)TODO

#-C$(KERNELDIR)在读取Makefile之前进入$(KERNELDIR)目录

#M=$(PWD)LDDINC=$(PWD)/../include传递2个变量给Makefile

#modules是$(KERNELDIR)中的Makefile的targetTODO

$(MAKE)-C$(KERNELDIR)M=$(PWD)LDDINC=$(PWD)/../includemodulesendif#清理

clean:

rm-rf*.o*~core.depend.*.cmd*.ko*.mod.c.tmp_versions#TODO

#产生依赖信息文件,如果存在的话则将其包含到Makefile中。

depend.dependdep:

$(CC)$(CFLAGS)-M*.c>.depend

ifeq(.depend,$(wildcard.depend))

include.depend

endif---

参考

1.[GNUmake中文手册]

2.[CFLAGS统一和gcc3.4]http:

//www.magiclinux.org/node/821

3.[LDD3源码学习笔记之scull_main]

4.

scull.h

/*

*scull.h--definitionsforthecharmodule

*

*Copyright(C)2001AlessandroRubiniandJonathanCorbet

*Copyright(C)2001O'Reilly&Associates

*

*Thesourcecodeinthisfilecanbefreelyused,adapted,

*andredistributedinsourceorbinaryform,solongasan

*acknowledgmentappearsinderivedsourcefiles.Thecitation

*shouldlistthatthecodecomesfromthebook"LinuxDevice

*Drivers"byAlessandroRubiniandJonathanCorbet,published

*byO'Reilly&Associates.Nowarrantyisattached;

*wecannottakeresponsibilityforerrorsorfitnessforuse.

*

*$Id:

scull.h,v1.152004/11/0417:

51:

18rubiniExp$

*/#ifndef_SCULL_H_

#define_SCULL_H_#include<linux/ioctl.h>/*neededforthe_IOWetcstuffusedlater*//*

*Macrostohelpdebugging

*///undef取消以前定义的宏

#undefPDEBUG/*undefit,justincase*/

#ifdefSCULL_DEBUG

#ifdef__KERNEL__

//内核空间,printk输出调试信息

/*Thisoneifdebuggingison,andkernelspace*/

#definePDEBUG(fmt,args)printk(KERN_DEBUG"scull:

"fmt,##args)

#else

//用户空间,fprintf输出调试信息

/*Thisoneforuserspace*/

#definePDEBUG(fmt,args)fprintf(stderr,fmt,##args)

#endif

#else

#definePDEBUG(fmt,args)/*notdebugging:

nothing*/

#endif#undefPDEBUGG

#definePDEBUGG(fmt,args)/*nothing:

it'saplaceholder*/#ifndefSCULL_MAJOR

//主设备号指定为0,表示由内核动态分配

#defineSCULL_MAJOR0/*dynamicmajorbydefault*/

#endif//baredevice的数量,也就是要请求的连续设备编号的总数

#ifndefSCULL_NR_DEVS

#defineSCULL_NR_DEVS4/*scull0throughscull3*/

#endif//TODO

#ifndefSCULL_P_NR_DEVS

#defineSCULL_P_NR_DEVS4/*scullpipe0throughscullpipe3*/

#endif/*

*Thebaredeviceisavariable-lengthregionofmemory.

*Usealinkedlistofindirectblocks.

*

*"scull_dev->data"pointstoanarrayofpointers,each

*pointerreferstoamemoryareaofSCULL_QUANTUMbytes.

*

*Thearray(quantum-set)isSCULL_QSETlong.

*/

//每个内存区字节数。

(量子长度)

#ifndefSCULL_QUANTUM

#defineSCULL_QUANTUM4000

#endif//数组长度(量子集长度)

#ifndefSCULL_QSET

#defineSCULL_QSET1000

#endif/*

*Thepipedeviceisasimplecircularbuffer.Hereitsdefaultsize

*/

//管道设备,环形缓冲大小。

#ifndefSCULL_P_BUFFER

#defineSCULL_P_BUFFER4000

#endif/*

*Representationofscullquantumsets.

*/

structscull_qset{

void**data;

structscull_qset*next;

};//使用scull_dev表示每个设备

structscull_dev{

structscull_qset*data;/*Pointertofirstquantumset*/

intquantum;/*thecurrentquantumsize*/

intqset;/*thecurrentarraysize*/

unsignedlongsize;/*amountofdatastoredhere*/

unsignedintaccess_key;/*usedbysculluidandscullpriv*/

structsemaphoresem;/*mutualexclusionsemaphore*/

structcdevcdev;/*Chardevicestructure*/

};//TODO什么用?

/*

*Splitminorsintwoparts

*/

//高四位

#defineTYPE(minor)(((minor)>>4)&0xf)/*highnibble*/

//低四位

#defineNUM(minor)((minor)&0xf)/*lownibble*//*

*Thedifferentconfigurableparameters

*/

externintscull_major;/*main.c*/

externintscull_nr_devs;

externintscull_quantum;

externintscull_qset;externintscull_p_buffer;/*pipe.c*//*

*Prototypesforsharedfunctions

*/intscull_p_init(dev_tdev);

voidscull_p_cleanup(void);

intscull_access_init(dev_tdev);

voidscull_access_cleanup(void);intscull_trim(structscull_dev*dev);ssize_tscull_read(structfile*filp,char__user*buf,size_tcount,

loff_t*f_pos);

ssize_tscull_write(structfile*filp,constchar__user*buf,size_tcount,

loff_t*f_pos);

loff_tscull_llseek(structfile*filp,loff_toff,intwhence);

intscull_ioctl(structinode*inode,structfile*filp,

unsignedintcmd,unsignedlongarg);/*

*Ioctldefinitions

*///TODO魔数什么用?

/*Use'k'asmagicnumber*/

#defineSCULL_IOC_MAGIC'k'

/*Pleaseuseadifferent8-bitnumberinyourcode*/#defineSCULL_IOCRESET_IO(SCULL_IOC_MAGIC,0)/*

*Smeans"Set"throughaptr,

*Tmeans"Tell"directlywiththeargumentvalue

*Gmeans"Get":

replybysettingthroughapointer

*Qmeans"Query":

responseisonthereturnvalue

*Xmeans"eXchange":

switchGandSatomically

*Hmeans"sHift":

switchTandQatomically

*/

#defineSCULL_IOCSQUANTUM_IOW(SCULL_IOC_MAGIC,1,int)

#defineSCULL_IOCSQSET_IOW(SCULL_IOC_MAGIC,2,int)

#defineSCULL_IOCTQUANTUM_IO(SCULL_IOC_MAGIC,3)

#defineSCULL_IOCTQSET_IO(SCULL_IOC_MAGIC,4)

#defineSCULL_IOCGQUANTUM_IOR(SCULL_IOC_MAGIC,5,int)

#defineSCULL_IOCGQSET_IOR(SCULL_IOC_MAGIC,6,int)

#defineSCULL_IOCQQUANTUM_IO(SCULL_IOC_MAGIC,7)

#defineSCULL_IOCQQSET_IO(SCULL_IOC_MAGIC,8)

#defineSCULL_IOCXQUANTUM_IOWR(SCULL_IOC_MAGIC,9,int)

#defineSCULL_IOCXQSET_IOWR(SCULL_IOC_MAGIC,10,int)

#defineSCULL_IOCHQUANTUM_IO(SCULL_IOC_MAGIC,11)

#defineSCULL_IOCHQSET_IO(SCULL_IOC_MAGIC,12)/*

*Theotherentitiesonlyhave"Tell"and"Query",becausethey're

*notprintedinthebook,andthere'snoneedtohaveallsix.

*(Thepreviousstuffwasonlytheretoshowdifferentwaystodoit.

*/

#defineSCULL_P_IOCTSIZE_IO(SCULL_IOC_MAGIC,13)

#defineSCULL_P_IOCQSIZE_IO(SCULL_IOC_MAGIC,14)

/*moretocome*/#defineSCULL_IOC_MAXNR14#endif/*_SCULL_H_*/

main.c

/*

*main.c--thebarescullcharmodule

*

*Copyright(C)2001AlessandroRubiniandJonathanCorbet

*Copyright(C)2001O'Reilly&Associates

*

*Thesourcecodeinthisfilecanbefreelyused,adapted,

*andredistributedinsourceorbinaryform,solongasan

*acknowledgmentappearsinderivedsourcefiles.Thecitation

*shouldlistthatthecodecomesfromthebook"LinuxDevice

*Drivers"byAlessandroRubiniandJonathanCorbet,published

*byO'Reilly&Associates.Nowarrantyisattached;

*wecannottakeresponsibilityforerrorsorfitnessforuse.

*

*/#include<linux/config.h>

#include<linux/module.h>

#include<linux/moduleparam.h>

#include<linux/init.h>#include<linux/kernel.h>/*printk()*/

#include<linux/slab.h>/*kmalloc()*/

#include<linux/fs.h>/*everything*/

#include<linux/errno.h>/*errorcodes*/

#include<linux/types.h>/*size_t*/

#include<linux/proc_fs.h>

#include<linux/fcntl.h>/*O_ACCMODE*/

#include<linux/seq_file.h>

#include<linux/cdev.h>#include<asm/system.h>/*cli(),*_flags*/

#include<asm/uaccess.h>/*copy_*_user*/#include"scull.h"/*localdefinitions*//*

*Ourparameterswhichcanbesetatloadtime.

*/intscull_major=SCULL_MAJOR;//主设备号

intscull_minor=0;//次设备号

intscull_nr_devs=SCULL_NR_DEVS;/*numberofbaresculldevices*/

intscull_quantum=SCULL_QUANTUM;//量子大小(字节)

intscull_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);

module_param(scull_quantum,int,S_IRUGO);

module_param(scull_qset,int,S_IRUGO);MODULE_AUTHOR("AlessandroRubini,JonathanCorbet");

MODULE_LICENSE("DualBSD/GPL");structscull_dev*scull_devices;/*allocatedinscull_init_module*///释放整个数据区。

简单遍历列表并且释放它发现的任何量子和量子集。

//在scull_open在文件为写而打开时调用。

//调用这个函数时必须持有信号量。

/*

*Emptyoutthesculldevice;mustbecalledwiththedevice

*semaphoreheld.

*/

intscull_trim(structscull_dev*dev)

{

structscull_qset*next,*dptr;

intqset=dev->qset;/*"dev"isnot-null*///量子集大小

inti;//遍历多个量子集。

dev->data指向第一个量子集。

for(dptr=dev->data;dptr;dptr=next){/*allthelistitems*/

if(dptr->data){//量子集中有数据

for(i=0;i<qset;i++)//遍历释放当前量子集中的每个量子。

量子集大小为qset。

kfree(dptr->data[i]);

kfree(dptr->data);//释放量子指针数组

dptr->data=NULL;

}

//next获取下一个量子集,释放当前量子集。

next=dptr->next;

kfree(dptr);

}

//清理structscull_devdev中变量的值

dev->size=0;

dev->quantum=scull_quantum;

dev->qset=scull_qset;

dev->data=NULL;

return0;

}

#ifdefSCULL_DEBUG/*useproconlyifdebugging*/

/*

*Theprocfilesystem:

functiontoreadandentry

*///在proc里实现文件,在文件被读时产生数据

//当一个进程读/proc文件,内核分配了一页内存,驱动可以写入数据返回用

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

当前位置:首页 > 人文社科

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1