上文我们说到整个字符设备的使用流程,实际上和我购车的整个流程是很类似的。但还有一部分没有进一步说明,就是当我要使用字符设备前,需要先open获取一个文件描述符fd之后,就可以通过fd来对这个字符设备进行操作了。为什么通过fd就可以对字符设备进行操作了呢?内部实现原理是怎样的呢?本篇文章将试图揭开这个内部流程。按照以往的惯例,我们还是以最通俗的方式讲解。若是您对这部分不管兴趣的话,可以略过。
首先,我们先大致的说一下linux内部的实现过程:
打开设备文件--》sys_open--》inode-->i_fop(chrdev_open)--》通过inode->i_rdev在cdev_map找到设备文件对应的cdev设备对象,将inode的icdev指向字符设备对象(这样,下回可以避免在设备中查找,直接使用icdev)--》将cdev中的ops赋值给filp->fop(内核每次打开字符设备时,会产生一个文件描述符fd和一个新的struct file对象来跟踪文件的操作,打开设备文件时,内核会将filp和fd关联起来,最后,将fd返回给用户空间)。
其次,让我试图用通俗的视角解释下。
第一、让我们把首次打开字符设备操作比喻成小明首次到4S店去取车及办理行车证等手续。其他的操作已经
在上文的描述中完成。
第二、让我们把首次打开字符设备的用户比喻成一个进程,那就是小明相当于一个进程。
第三、进程都维护着一个文件描述符表,每次打开设备文件,最终会得到一个文件描述符fd。那我们就可以
将这个字符设备的文件描述符fd比喻成小明新买的车的一个钥匙,那么,我们可以想象其实小明可以
有n多的钥匙,有的是用来开车的,有的是用来开出租屋的门(这还顺便可以解释多个fd对应一个
设备文件的情况,就像一个房间可以有多把钥匙,多个人(进程)都可以拿钥匙操作房门)等,这
么一讲来,其实,我们每个人无形中都有这么一张文件描述符表。
好了,现在来看我们首次取车的流程:我们在取车之前,已经都订好了自己的车牌,还为车子做了登记,当我们第一次拿到车钥匙(文件描述符fd)首次打着火的准备开回家的时候(sys_open),其实,看上去这么一个简单的过程,其实,中间无形中发生了一些列过程:在公安局(车管所)建立你的车的档案及在先前的车牌号的档案库中找到先前注册的车牌号(相当于在cdev_map中查找设备文件对应的cdev设备对象)并将两者建立联系,从此以后,公安局默认你以后上路的车就是符合你登记的车资料(换而言之,公安局以后就认为你开的车就是他在系统中定义好的功能的车子),否则,就算你非法改装车辆,违法行为(相当于欺骗内核)。最后,实际上你自己的无形中维护的那张文件描述符表从你为车打着火的那一刹那,你在文件描述符表的位置就固定了(也就是你以后就知道这个钥匙(文件描述符fd)就是为车打火的),而且,你也默认了打着火后的车子的行为就是我想要的车子的行为,就相当于fd通过文件描述符最终于设备节点id中的fop建立的联系。从今以后,你想都不用想,想开车就直接拿钥匙去打火出门,也不用去公安局登记,非常方便。
不知,说到这里你是否有点明白,有点拗口,希望对你有帮助。
小明这时的思想猛的回来,还要去银行取钱呢,想到这里,风驰电掣般的驾车驶向银行。。。。。。
阅读(1821) | 评论(0) | 转发(2) |