Linux设备模型(1)_基本概念

作者:wowo 发布于:2014-2-27 17:01 分类:统一设备模型

1. 前言

在“Linux内核的整体架构”中,蜗蜗有提到,由于Linux支持世界上几乎所有的、不同功能的硬件设备(这是Linux的优点),导致Linux内核中有一半的代码是设备驱动,而且随着硬件的快速升级换代,设备驱动的代码量也在快速增长。个人意见,这种现象打破了“简洁就是美”的理念,是丑陋的。它导致Linux内核看上去非常臃肿、杂乱、不易维护。但蜗蜗也知道,这不是Linux的错,Linux是一个宏内核,它必须面对设备的多样性,并实现对应的驱动。

为了降低设备多样性带来的Linux驱动开发的复杂度,以及设备热拔插处理、电源管理等,Linux内核提出了设备模型(也称作Driver Model)的概念。设备模型将硬件设备归纳、分类,然后抽象出一套标准的数据结构和接口。驱动的开发,就简化为对内核所规定的数据结构的填充和实现。

本文将会从设备模型的基本概念开始,通过分析内核相应的代码,一步一步解析Linux设备模型的实现及使用方法。

2. Linux设备模型的基本概念

2.1 Bus, Class, Device和Device Driver的概念

下图是嵌入式系统常见的硬件拓扑的一个示例:
device_toplogy

硬件拓扑描述Linux设备模型中四个重要概念中三个:Bus,Class和Device(第四个为Device Driver,后面会说)。

Bus(总线):Linux认为(可以参考include/linux/device.h中struct bus_type的注释),总线是CPU和一个或多个设备之间信息交互的通道。而为了方便设备模型的抽象,所有的设备都应连接到总线上(无论是CPU内部总线、虚拟的总线还是“platform Bus”)。

Class(分类):在Linux设备模型中,Class的概念非常类似面向对象程序设计中的Class(类),它主要是集合具有相似功能或属性的设备,这样就可以抽象出一套可以在多个设备之间共用的数据结构和接口函数。因而从属于相同Class的设备的驱动程序,就不再需要重复定义这些公共资源,直接从Class中继承即可。

Device(设备):抽象系统中所有的硬件设备,描述它的名字、属性、从属的Bus、从属的Class等信息。

Device Driver(驱动):Linux设备模型用Driver抽象硬件设备的驱动程序,它包含设备初始化、电源管理相关的接口实现。而Linux内核中的驱动开发,基本都围绕该抽象进行(实现所规定的接口函数)。

注:什么是Platform Bus?
在计算机中有这样一类设备,它们通过各自的设备控制器,直接和CPU连接,CPU可以通过常规的寻址操作访问它们(或者说访问它们的控制器)。这种连接方式,并不属于传统意义上的总线连接。但设备模型应该具备普适性,因此Linux就虚构了一条Platform Bus,供这些设备挂靠。

2.2 设备模型的核心思想

Linux设备模型的核心思想是(通过xxx手段,实现xxx目的):

1. 用Device(struct device)和Device Driver(struct device_driver)两个数据结构,分别从“有什么用”和“怎么用”两个角度描述硬件设备。这样就统一了编写设备驱动的格式,使驱动开发从论述题变为填空体,从而简化了设备驱动的开发。

2. 同样使用Device和Device Driver两个数据结构,实现硬件设备的即插即用(热拔插)。
在Linux内核中,只要任何Device和Device Driver具有相同的名字,内核就会执行Device Driver结构中的初始化函数(probe),该函数会初始化设备,使其为可用状态。
而对大多数热拔插设备而言,它们的Device Driver一直存在内核中。当设备没有插入时,其Device结构不存在,因而其Driver也就不执行初始化操作。当设备插入时,内核会创建一个Device结构(名称和Driver相同),此时就会触发Driver的执行。这就是即插即用的概念。

3. 通过"Bus-->Device”类型的树状结构(见2.1章节的图例)解决设备之间的依赖,而这种依赖在开关机、电源管理等过程中尤为重要。
试想,一个设备挂载在一条总线上,要启动这个设备,必须先启动它所挂载的总线。很显然,如果系统中设备非常多、依赖关系非常复杂的时候,无论是内核还是驱动的开发人员,都无力维护这种关系。
而设备模型中的这种树状结构,可以自动处理这种依赖关系。启动某一个设备前,内核会检查该设备是否依赖其它设备或者总线,如果依赖,则检查所依赖的对象是否已经启动,如果没有,则会先启动它们,直到启动该设备的条件具备为止。而驱动开发人员需要做的,就是在编写设备驱动时,告知内核该设备的依赖关系即可。

4. 使用Class结构,在设备模型中引入面向对象的概念,这样可以最大限度地抽象共性,减少驱动开发过程中的重复劳动,降低工作量。

原创文章,转发请注明出处。蜗窝科技,www.wowotech.net

标签: Kernel 内核 设备模型 Device Model 驱动开发

评论:

LLEo
2022-03-07 14:35
感谢wowo 大佬
抚泪
2021-12-31 16:41
看了2个多星期,终于对设备模型有个基本的概念了,感谢wowo。
lxq
2021-12-02 10:50
赞赞赞赞!!!
三变
2021-08-10 14:16
写的很好,5年前 我的师傅看着你的文章学习
到了今天 我靠着你的博文入门
好的技术 好的博文永不过时
董先生
2021-10-07 16:51
@三变:好有道理,好的博文永不过时!!!
alilili
2020-07-02 19:06
2020前来考古
lin
2022-11-07 14:59
@alilili:22年前来学习
ty
2023-06-15 15:50
@lin:23年前来学习
HYH
2019-09-27 14:20
以spi为例,spi的控制器(master端)注册为platform设备,而diver就是驱动挂在使用spi传输的外设和spi控制器之间正常通信工作,该driver也就是platform driver?这样理解对吗?求大神指点
ysh
2019-09-27 14:22
@HYH:很难理解spi dev、drv和platform dev、drv之间的关系
Dongwei
2019-11-13 14:08
@ysh:spi总线实际存在,platform总线实际并不存在,是抽象出来的。所以spi总线在注册时,实际还是device与driver,只是用platform的形式将两者分别封装起来。
Dongwei
2019-11-13 14:09
@ysh:spi总线实际存在,platform总线实际并不存在,是抽象出来的。所以spi总线在注册时,实际还是device与driver,只是用platform的形式将两者分别封装起来。
wgy504
2019-08-30 10:45
原文中“就是在编写设备驱动时,告知内核该设备的依赖关系即可。”
能否举一个例子啊?
liaocj
2019-03-12 17:09
每看一次就会有不同的收获
wyz
2019-03-06 02:50
版主,网站打开很慢……可以改进下吗。文章写的鞭辟入里,我以赞助10元
wowo
2019-03-07 19:16
@wyz:多谢支持~~慢可能是因为服务器在香港吧,估计没法改进啊。
sdssgl
2019-01-19 23:46
2.2 设备模型的核心思想

而对大多数热拔插设备而言,它们的Device Driver一直存在内核中。当设备没有插入时,其Device结构不存在,因而其Driver也就不执行初始化操作。当设备插入时,内核会创建一个Device结构(名称和Driver相同),此时就会触发Driver的执行。这就是即插即用的概念
/***************************************************************************************
* 对于此处个人的理解:
***************************************************************************************/
此处的设备插入,并非真实物理设备的插入,而是通过dts或板级文件添加注册设备,即插入;当没有对应的dts文件或者板级文件的设备注册时,Device结构不存在,故Driver不会执行初始化操作
wowo
2019-01-21 20:51
@sdssgl:DTS仅仅是“插入”的一个子集。

发表评论:

Copyright @ 2013-2015 蜗窝科技 All rights reserved. Powered by emlog