linux bus、driver、device及三者的关系
一、概念
1、bus
总线是处理器和设备之间的通道。总线有多种类型,每种总线可以挂载多个设备。
2、driver
驱动程序是在CPU运行时,提供操作的软件接口。所有的设备必须有与之配套驱动程序才能正常工作。一个驱动程序可以驱动多个类似或者完全不同的设备。
3、device
设备就是连接在总线上的物理实体。设备是有功能之分的。具有相同功能的设备被归到一个类,如输入设备(鼠标,键盘,游戏杆等)。
二、三者的关系
总线上有两个重要的链表:
1)设备(device)链表;
2)驱动(driver)链表
每次出现一个设备就要向总线汇报,每次出现一个驱动,也要向总线注册。系统初始化的时候,会扫描连接了哪些设备,为每一个设备建立起一个struct device的变量,并加入设备链表;每次注册一个驱动,就要准备一个struct device_driver结构的变量,并加入驱动链表。这样所有的设备都挂载到总线上,当加载驱动时,驱动就去总线上找到自己对应的设备,或者先把驱动注册上,来了一个设备就去总线找驱动。如果只有设备却没有对应的驱动,那么设备无法工作,如果只有驱动却没有设备,驱动也起不了任何作用。
每种总线下面可以挂载许多设备。(通过kset devices)
每种总线下可以用很多驱动。(通过包含一个kset drivers)
每个驱动可以处理一个或多个设备。
三、如何注册驱动、添加设备
1、注册驱动
注册一个驱动,首先把驱动链入到驱动(driver)链表中,然后从设备(device)链表中逐个寻找,看有没有可以关联的设备。如果找到关联的设备,就执行probe函数。
具体流程如下:
platform_driver_register-》driver_register-》bus_add_driver-》driver_attach-》bus_for_each_dev-》__driver_attach
-》driver_probe_device-》really_probe
2、添加设备
添加一个设备,首先把设备链入到设备(device)链表中,然后从驱动(driver)链表中逐个寻找,看有没有可以关联的驱动。如果找到关联的驱动,就执行probe函数。
具体流程如下:
device_add-》bus_add_device-》bus_probe_device-》device_attach-》bus_for_each_drv-》__device_attach
-》driver_probe_device-》really_probe
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_kset和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被注册到总线上,都会执行上面的过程。
linux bus、driver、device及三者的关系相关推荐
- linux设备驱动——bus、device、driver加载顺序与匹配流程
文章目录 1. 前言 2. 概念 2.1. 数据结构 2.2. probe函数 3. bus.device.driver加载顺序 3.1. 加载方式 3.2. 加载顺序 4. device.drive ...
- 设备驱动模型:device, bus, driver之间的联系
对于驱动工程师而言,在移植porting对应设备的driver时,要在devicetree中增加对应的设备节点,其中有一个compatible属性,这个属性的字符串要和driver里面的of_devi ...
- px4驱动linux,S.Bus Driver for Linux
用于 Linux 的 S.Bus 驱动 S.Bus Driver for Linux 允许基于 Linux 的无人机通过串行端口从 Futaba S.Bus 接收机 访问多达 16 个通道. 驱动程序 ...
- Linux SDIO WIFI Marvell8801/Marvell88w8801(六) --- Marvell Linux Wi-Fi driver介绍-WIFI插入卡槽内发生的事情
代码工程的GITHUB连接:点进进入GITHUB仓库 https://github.com/sj15712795029/stm32f1_marvell88w8801_marvell8801_wifi ...
- Linux virtio-net driver
1,基本概念 virtio 是对半虚拟化 hypervisor 中的一组通用模拟设备的抽象.它允许 hypervisor 导出一组通用的模拟设备,并通过一个通用的应用编程接口(API)让它们变得可用. ...
- Linux and the Device Tree
来之\kernel\Documentation\devicetree\usage-model.txt Linux and the Device Tree ----------------------- ...
- linuxPci驱动获取指定设备bus、device以及devfn数据方式
在vxworks系统中,调用pciFindDevice()函数可以直接获取到指定设备的bus.deviceNo以及devfn数据信息.相对于linux系统,vxworks编写驱动相对简单一些. lin ...
- 总线驱动:Bus driver - USB driver for example
Table of Contents Bus driver Adapter, bus and device drivers Example of device driver Device identif ...
- [Linux Audio Driver] SM6350平台音频bring up ( 一 )
0. 背景 这个是高通5G平台,音频的内容改的比较多,比较直接的是platform.c就直接移动到vendor了:目前 高通那边的趋势还是把音频逐渐从kernel剥离,android 7/androi ...
最新文章
- 通过属性值从对象数组中获取JavaScript对象[重复]
- MySQL通过存储过程使用循环结构循环创建数据,以及批量数据的导入导出
- C# 监控统计 程序执行 时间
- 领域驱动设计,让程序员心中有码
- [C++STL]C++实现stack容器适配器
- POJ 3461 字符串匹配(KMP / 哈希(有推导))
- 两顶点的路径长度为k_计算两个顶点之间的所有可能路径
- opencv2.4.3通过不同方式访问图像像素
- jmeter 添加虚拟IP
- OkHttp 3.x 源码解析之Dispatcher分发器
- 读书笔记三、pandas之重新索引
- Android各版本代号、版本号、API/NDK级别、发布时间及市场份额
- 第八集:魔法阵 NTT求循环卷积
- win10环境下python3如何使用PyV8
- 如何使用Eclipse开发安卓手机程序在手机上运行并设置真机启动
- 全面详解互联网企业开放API的 “守护神”
- 170928 逆向-Reversing.kr(Direct3D_FPS)
- 奇怪的键盘按a截图了
- 听见丨戴森召回逾10万台进口空气净化暖风器 沃尔沃开始在普通家庭展开自动驾驶项目
- ESP8266烧录选项中的QIO 和 DIO解释