分类: LINUX
2015-09-01 11:15:08
Linux 设备驱动模型中,按照层次的组织结构,抽象成总线(struct bus_type),设备(struct device),驱动(struct device_driver)的层次组织形式,这是最原始的抽象结构,在此基础之上,根据不同类型的总线/设备/驱动,有形成了更高层次的组织结构,如virtio总线(struct bus_type virtio_bus),virtio设备(struct virtio_device),virtio驱动(struct virtio_driver)等。
不同的抽象层次构成一颗网状的树,linux内核通过驱动模型:kobject,kset来组织树的结构。
上图说明了总线通过两个数据结构:devices_ket和driver_kset来管理注册在此总线上的所有的设备和驱动,为了方便遍历,linux增加了klist_devices和klist_drivers用来实现设备和驱动的遍历。
理解linux驱动模型,最重要的是理解设备与驱动的匹配过程,即在何时,驱动与设备如何实现匹配?
总结起来,设备的注册时机为调用device_register(),将devices注册到总线的devices_kset上,同理,驱动的注册为调用driver_register将驱动注册到总线的drivers_kset上。
下图对照说明了Device和Driver的注册过程。
设备与驱动的匹配主要有以下几个点:
(1)如果总线的match函数非空,调用总线的match函数
(2)如果总线的probe函数非空,调用总线的probe函数,然后会在总线的probe函数中调用驱动的probe函数
(3)如果总线的probe函数为空,则直接调用驱动的probe函数
另外,bus_for_each_drv()是对BUS上所有的Driver都进行__device_attach()操作;同样的,bus_for_each_dev()是对BUS上所有的Device都进行__driver_attach()操作。
那么,这些函数的执行时机在哪呢?
只要有device或device_driver被注册到总线上,都会执行上面的过程。