Linux设备文件浅析

上传人:gg****m 文档编号:204551824 上传时间:2021-10-26 格式:DOC 页数:5 大小:66KB
返回 下载 相关 举报
Linux设备文件浅析_第1页
第1页 / 共5页
Linux设备文件浅析_第2页
第2页 / 共5页
Linux设备文件浅析_第3页
第3页 / 共5页
Linux设备文件浅析_第4页
第4页 / 共5页
Linux设备文件浅析_第5页
第5页 / 共5页
亲,该文档总共5页,全部预览完了,如果喜欢就下载吧!
资源描述

《Linux设备文件浅析》由会员分享,可在线阅读,更多相关《Linux设备文件浅析(5页珍藏版)》请在金锄头文库上搜索。

1、linux下的文件分为常规文件和设备文件”常规文件一定在某一个设备上被存储,不论这个设备是真实的还是虚拟的,这里的设备是linux中vfs层中的设备,也就是前面所说的设 备文件中的设备,vfs层的设备分为字符设备和块设备,字符设备可以类比为一个fifo的队 列,无论读还是写都必须顺序进行,而块设备就可以随机进行读写,常规的文件一般都在 块设备上被存储,包括设备文件本身也在一个块设备上被存储着,可以说vfs层解决了这种 混乱,它提供给上面的操作者一个十分统一的接口 ,实际上vfs下面十分不雅,败絮其中 吗?等你看了 linux源代码就不会这么认为了 # linux内核是分层次的,vfs仅仅是其中

2、的 一个罢了,即使下面很乱也不是很无序的乱,总体看来是很乱,那是因为你混合看所有设备 那当然混乱,因为字符设备和块设备的管理方式就不同,如果理一下思路就会很自然的想 到在vfs接口下面有三条线,一条是常规文件,一条是字符设别文件,另一条就是块设备文 件。linux用很好的数据结构组织了两类设备文件,对于字符设备比较简单,就是将所有的 字符设备都置于一个map中,就是cdev_map ,所有的字符设备在注册的时候都会加入这 个 map :int register_chrdev(unsigned int major; const char name, struct file_operations

3、*fops)struct char_device_struct *cd;struct cdev *cdev;char *s;int err = -ENOMEM;cd = _register_chrdev_region(major/ 0, 256, name);cdev = cdev_alloc();if (Icdev)goto out2;cdev-ow ner = fops-ow ner;cdev- ops = fops;strcpy(cdev-kobj.name, name);for (s = strchr(cdev-kobj.name, /); s; s = strchr(sf /)*s

4、=err = cdev_add(cdev, MKDEV(cd-major, 0), 256);cd-cdev = cdev;return major ? 0 : cd-major;注意这个map并不是一个字符设备的链表,而是一个hash表,这个map主要作用就是 和2.6内核的新的设备模型联系,也就是和kobject联系Jinux中真正将所有的字符设备 连成链表的是上面函数里面的char_device_struct结构体,很早以前写过一篇谈谈 Iinux2.6内核的驱动框架中讲到驱动的两条线索,其中以kobject连接起来的第一条线 索直取用户空间其实就是SJ了这里的这个map在这个map将把

5、任务交给了 vfs的接口。hash组织的kobj.map效率非常高,其实这里的hash函数很简单,就是设备号和255相除取余,将hash值相等的kobject用next字段连接成一个链表,然后在需要查找某些值 的时候通过hash找到链表然后遍历链表通过一个回调函数进行精确比对最终找到需要的 结构:struct kobj_map struct probe struct probe *next;dev_t dev;unsigned long range;struct module *owner;kobj_probe_t勺et;这就是那个精确比对的回调函数,这个创意在于将比对策略一起放入了 hash

6、节点中z这样可以灵活实现不同的比对策略。int (*lock)(dev_tz void *);void *data; *probes255;/255 个 hash 桶struct rw_semaphore *sem;;每当打开一个字符设备时,从这个map中得到一个cdev结构体,而cdev中有一个 file_operations字段,在默认的open函数中,用这个file.operations字段替换字符设备 的默认的file_operations字段,然后从此用户就可以用这个file_operations来操作字符 设备了,这就是狸猫换太子了。对于块设备远远比字符设备复杂,但是看起来要比字符

7、设备有层次感,块设别也有一个前面 的hash表,只不过它里面映射的不是简单的vfs层的块设备了 ,而是更为底层通用块设 备,就是gendisk,为何要这样?就是因为块设备可以利用缓存,这在linux中是很重要的, 可以大大提高效率,因此必须在真正的块设备层上面提供一个统一的缓存管理的层次,最 好和常规文件的缓存管理统一用一套机制,这样的结果就是block-device层次,其实 block.device是一个vfs和gendisk之间的粘结层,可以为统一缓存管理机制提供更加统 一的接口(gendisk很底层,不适合做这件事),为了和常规文件一致的管理缓存就必须一 套和常规文件一致的file_o

8、perations结构体,linux的block设备恰恰提供了这个: def_blk_fopso另外就是以上的file_operations必须固定,不能让不同的disk任意设置, 因为虽然底层设备不同,可是缓存管理机制是统一的,缓存不属于底层,而属于vfs。 gendisk就是再往下的块设备层次了 ,它主要管理磁盘结构信息,比如分区信息等等,再往 下就是IDE , SCSI这些特殊的层次了。以上是字符设备和块设备文件的vfs架构,那么常规文件呢?前面说过,常规文件都在块设 备中,因此常规文件的操作就成了最终的块设备的操作,最终在经过了缓存层次之后就到了 块设备的架构了,最终也要经过gendi

9、sk到达底层硬件。还有一类设备就是网络设备,比如网卡之类的,可是却没有在任何地方看到网络设备的设备 文件,这到底是为什么?这就要从TCP/IP协议栈和BSD套接字说起了,在tcp/ip之前, 操作网络设备是件很平常的事可是tcp/ip之后就没人再直接操作网络设备进行通信了, 取而代之的是用协议栈进行通信,tcp/ip规定应用通信信道是应用层的两个进程之间建立 的信道,很多情况下,信道应该是独占的,而设备意味着共享,大家都可以用,因此建立设 备文件并没有问题。可是在tcp/ip之后,网络设备就被抽象成了一个通信信道,BSD套接 字实现了这一点,因此通信就是两个进程独占一个信道进行通信(不考虑广播

10、和组播),网 络设备就不能随意被共享了,更大的意义是没有必要被共享,没有人再直接操作网络设备进 行通信,所有人都是通过套接字用协议栈进行通信的,而一个套接字就是一个信道的一个 端点,被一个进程独占,并且在通信开始时动态建立,通信开始时间不早于进程创建时间, 因此就把网络设备的管理交给了进程,进程可以很方便的通过协议栈管理设备和应用设备, 古老的ifconfig不就是通过套接字的ioctl配置设备的吗?这并不违背unix的一切皆文件 的理念,套接字本身也是通过vfs操作的,只是有了协议栈和套接字用户接口 ,第一是没 有必要再提供网卡设备文件了,第二就是网络通信信道的独占性和协议封装规则已经作为 协议栈的标准存在了,底层的硬件网卡也遵循这些协议栈标准(IEEE802.X ),因此操作系统 必须提供标准的操作方式而不是将操作自由留给用户,用户如果不懂协议栈标准就无法操 作设备并且用设备通信,而协议栈标准是统一的,因此必须由操作系统提供,然后把可以微 调的配置用套接字接口的形式留给用户操作和配置。类似于管道,很多无名管道也没有设 备文件,只要在进程中以独占方式操作的文件描述符都没有必要有设别文件,一切皆文件指 的是vfs这个层次而不是必须要在文件系统有永久记录

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 办公文档 > 其它办公文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号