Linux设备模型中三个很重要的概念便是总线,设备,驱动.即bus,device,driver,而实际上内核中也界说了这么一些数据结构,他们是 struct bus_type,struct device,struct device_driver,这三个重要的数据结构都来自一个当地,include/linux/device.h.咱们知道总线有很多种,pci总线,scsi总线,usb 总线,所以咱们会看到 Linux 内核代码中呈现pci_bus_type,scsi_bus_type,usb_bus_type,他们都是struct bus_type类型的变量.而struct bus_type结构中两个非常重要的成员便是 struct kset drivers 和 struct kset devices.kset 和另一个叫做 kobject正是 Linux Kernel 2.6中设备模型的根本元素,但此处咱们却不肯多讲,由于暂时不必去知道他们.咱们的生射中会遇见许许多多的人和事,但更多的人和事与咱们仅仅擦肩而过,仅仅咱们生射中的过客罢了.在咱们人生的电影中,他们或许只要一个镜头,乃至那一个镜头后来也被编排掉了.这儿咱们只需要知道,drivers 和 devices 的存在,让struct bus_type与两个链表联络了起来,一个是 devices 的链表,一个是drivers 的链表,也便是说,知道一条总线所对应的数据结构,就能够找到这条总线所相关的设备有哪些,又有哪些支撑这类设备的驱动程序.
而要完结这些,就要求每次呈现一个设备就要向总线报告,或许说注册,每次呈现一个驱动,也要向总线报,或许说注册.比方体系初始化的时分,会扫描连接了哪些设备,并为每一个设备树立起一个 struct device的变量,每一次有一个驱动程序,就要预备一个 struct device_driver结构的变量.把这些变量通通参加相应的链表,device刺进devices链表,driver刺进drivers链表. 这样经过总线就能找到每一个设备,每一个驱动.
但是,假设计算机里只要设备却没有对应的驱动,那么设备无法作业.反过来,假使只要驱动却没有设备,驱动也起不了任何效果.在他们遇见互相之前,两边都如同路埂的野草,一个飘啊飘,一个摇啊摇,谁也不知道未来在哪里,只能在生命的风里飘摇.所以总线上的两张表里就渐渐的就挂上了那许多孑立的魂灵.devices 开端多了,drivers 开端多了,他们像是两个来自国际,devices 们互相取暖,drivers 们一同狂欢,但他们有一点是相同的,都仅仅在等候归于自己的那个另一半.
看代码的我,一向猎奇的想知道,他们是否和咱们实际中相同,有些人注定是等他人,而有些人是注定被人等的.
struct bus_type中为 devices 和 drivers 预备了两个链表,而代表 device的结构体struct device中又有两个成员,struct bus_type *bus 和struct device_driver *driver,相同,代表driver 的结构体 struct device_driver相同有两个成员,struct bus_type *bus和 struct list_head devices,struct device和 struct device_driver的界说和 struct bus_type相同,在 include/linux/device.h 中.凭一种男人的直觉,能够知晓,struct device中的 bus记载的是这个设备连在哪条总线上,driver记载的是这个设备用的是哪个驱动,反过来,struct device_driver中的bus代表的也是这个驱动归于哪条总线,devices记载的是这个驱动支撑的那些设备,没错,是devices(复数),而不是device(奇数),由于一个驱动程序能够支撑一个或多个设备,反过来一个设备则只会绑定给一个驱动程序.
所以咱们想知道,关于 bus,关于 device,关于 driver,他们是怎么树立联络的呢?换言之,这三个数据结构中的指针是怎么被赋值的?绝对不或许发生的作业是,一旦为一条总线请求了一个struct bus_type的数据结构之后,它就知道它的devices链表和drivers链表会包括哪些东西,这些咚咚必定不会是先天就有的,只能是后天填进来的.而详细到usb 体系,完结这个作业的便是usb core.usb core的代码会进行整个 usb 体系的初始化,比方请求struct bus_type usb_bus_type,然后会扫描 usb 总线,看线上连接了哪些usb设备,或许说 root hub上连了哪些usb设备,比方说连了一个usb键盘,那么就为它预备一个struct device,依据它的实际状况,为这个struct device赋值,并刺进devices链表中来.又比方root hub上连了一个一般的hub,那么除了要为这个hub 自身预备一个 struct device以外,还得持续扫描看这个 hub上是否又连了其他设备,有的话持续重复之前的作业,这样一向进行下去,直到完结整个扫描,终究就把
usb_bus_type中的 devices链表给树立了起来. 那么 drivers链表呢?这个就不必bus方面主动了,而该由每一个 driver 自身去 bus上面挂号,或许说挂牌。
bus上的两张链表记载了每一个device和driver,那么device和driver这两者之间又是怎么联络起来的
呢?此时,有必要抛出这样一个问题,先有device仍是 driver?
好久好久以前,在那热情焚烧的年月里,先有的是device,每一个要用的device在计算机发动之前就现已插
好了,插放在它应该在的方位上,然后计算机发动,然后操作体系开端初始化,总线开端扫描设备,每找到一个设备,就为其请求一个struct device结构,而且挂入总线中的devices链表中来,然后每一个驱动程序开端初始化,开端注册其struct device_driver结构,然后它去总线的devices链表中去寻觅(遍历),去寻觅每一个还没有绑定driver的设备,即struct device中的struct device_driver指针仍为空的设备,然后它会去调查这种设备的特征,看是否是他所支撑的设备,假如是,那么调用一个叫做device_bind_driver的函数,然后他们就结为了两姓之好.换句话说,把struct device中的struct device_driver driver指向这个driver,而struct device_driver driver把struct device参加他的那张struct list_headdevices链表中来.就这样,bus,device,和driver,这三者之间或许说他们中的两两之间,就给联络上了.知道其中之一,就能找到别的两个.一荣俱荣,一损俱损.
但现在状况变了,在这红莲开放的日子里,在这樱花伤逝的日子里,呈现了一种新的名词,叫热插拔.device
能够在计算机发动今后在刺进或许拔出计算机了.因而,很难再说是先有device仍是先有driver了.由于都有或许.device能够在任何时刻呈现,而driver也能够在任何时刻被加载,所以,呈现的状况便是,每逢一个
struct device诞生,它就会去bus 的drivers链表中寻觅自己的另一半,反之,每逢一个一个struct
device_driver诞生,它就去bus的devices链表中寻觅它的那些设备.假如找到了适宜的,那么ok,和之前
那种状况一下,调用device_bind_driver绑定好.假如找不到,没有关系,等候吧,比及昙花再开,比及景色看
透,心中信任,这国际上总有一个人是你所等的,仅仅还没有遇到罢了.