字符设备是linux系统中应用最广泛的一类设备,它能够像字节流一样顺序访问, 通过直接传输来自用户进程的数据而不经过缓存。字符设备驱动的优点在于它不和硬 件相关,因为每台计算机都有内存。字符设备驱动只是操作某些内存,通过k」11alfoc进 行分配。任何人都可以编译和运行,而且可以将其移植到Linux支持的所有计算机平 台上。 4.1Linux字符设备驱动结构 编写Linux字符设备去冬程序首先要熟悉三个结构体,即file_operations(文件 操作)、file(文件)、和inode(节点)。 4.1.1 file--operations结构体 file一perations为应用程序提供接口,是系统调用和驱动程序光澈的重要数据结构。 结构体中每一个成员都对应着一个系统调用。/dev目录下的设备文件和驱动程序的连 接就是通过file_operations结构体建立的。这个结构体的定义在内核源码的 kemel/linux/fs。h中。fil屯。peration结构中的每个成员都是指向函数的指针,指向驱动 中的函数,这些函数实现一个特别的操作,或者对于不支持的操作留置为NULL。当 指定为NuLL指针时内核确切的行为针对每个函数是不同的。structfil处operations是 一个字符设备把驱动的操作和设备号联系在一起的接口,是一系列指针的集合,每个 被打开的文件都对应于一系列的操作,这就是file一perations,用来执行一系列的系统 调用。 file_operations结构体中的成员函数是字符设备驱动程序设计的主体内容,这些函 数会在应用程序进行Linux的open、read、write、elose和ioetl等系统调用时最终被调 用。file_operations结构体在2.6版本内核中的定义如下: Struetfile_operations{ stroCtmodule*owner;//拥有该结构的模块的指针,一般为 THISMODULES loff--t(*11Seek)(struetfile*,loff--t,int);//用来修改文件当前的读 写位置 ssiZe_t(*read)(struetfile*,Char_user*,size_t,loff_t*);// 从设备中同步读取数据 ssiZe_t(*aio_read)(struetkioeb*,ehar_user*,size_t,loff--t); //初始化一个异步的读取操作 ssizet(*write)(struetfile*, eonsteharuser*,sizet,lofft); //向设备发送数据 ssize_t(*aio_write)(struetkioeb*, eonstehar_user*,size_t,loff_t); //初始化一个异步的写入操作; int(*readdir)(Structfile*,void*,findir_t);_//仅用于读取目 录,对于设备文件,该字段为NULL unsignedint(*poll)(struetfile*, Struetpoll_table_struet*);//轮 询函数,判断目前是否可以进行非阻塞的读取或写入 int(*ioetl)(struetinode*, struetfile*, unsignedint, unsignedlong); //执行设备工/O控制命令 long(*unloeked_ioetl)(struetfile*, unsignedint, unsignedlong);// 不使用BLK文件系统,将使用此函数代替 1octl long(*eompat_i。 etl)(struetfile*, unsignedint, unsignedlong);// 在64位系统上 int(*mmap)(struetinode*, struetfile*, Struetvm--area_struet*);// 用于请求将设备内存映射到进程地址空间 int(*open)(struetinode*, struetfile*);//打开 int(*flush)(struetfile*); int(*release)(struetinode*, Struetfile*);//关闭 int(*syneh)(struetfile*, Struetdentry*, intdatasyne);//刷新等 待处理数据 int(*aio_fsyne)(struetkioeb*, intdatasyne);//异步fsyne int(*fasyne)(int, Struetfile*,int);//通知设备FASYNC标志位发 生变化 int(*loek)(struetfile*,int, Struetfile_loek*);//用于实现文件锁 定,锁定是常规文件不可缺少的特性,但设备驱动程序几乎从来不会实现这个方法 ssize_t(*ready)(struCtfile*, eonststruetiovee*, unsignedlong,loff--t *); Ssize_t(*writev)(Struetfile*, eonststruetiovee*, unsignedlong,lof几t *);//用来实现“分散/聚集”型的读写操作。应用程序有时需要进行涉及多个内 存区域的单次读或写操作,利用上面这些系统调用可完成这类工作,而不必强加额外 的数据拷贝操作。 ssiZe_t(*sendfile)(struCtfile*,loff--t*,size_t,read_aetor_t,void *); ssize_t(*sendpage)(struetfile*, struetpage*,int,size_t,loff--t *,int); unsignedlong(*get_unmapped_area)(struetfile*, unsignedlong,unsigned 10ng, unsignedlong, unsignedlong);//进程地址空l间找到一个将底 层设备中的内存段映射的位置 int(*check_flags)(int);//允许模块检查传递给fcntl调用的标志
本页地址 http://www.jybase.net/linux/20120612950.html
【百度搜索更多】
【谷歌搜索更多】
Armitage是一款Java写的Metasploit图形界面化的攻击软件,可以用它结...
你还在使用密码登录吗?作为一个最直接、容易理解以及使用最...
禁止TCP连接80端口,只开放某些IP通过TCP访问80端口: #禁止所有IP对...