设备模型(的意义)
降低设备多样性带来的Linux驱动开发的复杂度,以及设备热拔插处理、电源管理等,Linux内核提出了设备模型概念。设备模型将硬件设备归纳、分类,然后抽象出一套标准的数据结构和接口。驱动的开发,就简化为对内核所规定的数据结构的填充和实现。
简单概括了下他们之间的层级关系:从上到下垂直调用,设备驱动的代码量占了大部分内核程序
设备模型分类
1. 字符设备
一个字节一个字节读写的设备,读取数据需要按照先后顺序读取,常见的字符设备有鼠标、键盘、串口、控制台和LED设备,每个字符设备在/dev目录下对应一个设备文件,linux用户程序通过设备文件(或称设备节点)来使用驱动程序操作字符设备。
2. 块设备
是指可以从设备的任意位置读取一定长度的数据设备。块设备如硬盘、磁盘、U盘和SD卡等存储设备。
3. 网络设备
网络设备比较特殊,不在是对文件进行操作,而是由专门的网络接口来实现。应用程序不能直接访问网络设备驱动程序。在/dev目录下也没有文件来表示网络设备。
对于字符设备和块设备来说,在/dev目录下都有对应的设备文件。linux用户程序通过设备文件或叫做设备节点来使用驱动程序操作字符设备和块设备。
设备类型
字符设备:字符设备驱动程序通常至少要实现open、close、read和write的系统调用。
上层应用如何调用底层驱动?
- 应用层的程序open设备文件,进入内核中,即虚拟文件系统中。
- VFS层的设备文件有对应的struct inode,其中包含该设备对应的设备号,设备类型,返回的设备的结构体。
- 在驱动层中,根据设备类型和设备号就可以找到对应的设备驱动的结构体,用i_cdev保存。该结构体中有很重要的一个操作函数接口file_operations。
- 在打开设备文件时,会分配一个struct file,将操作函数接口的地址保存在该结构体中。
- VFS层 向应用层返回一个fd,fd是和struct file相对应,这样,应用层可以通过fd调用操作函数,即通过驱动层调用硬件设备了。
字符终端(/dev/console)和串口(/dev/ttyS0以及类似设备)就是两个字符设备,它们能很好的说明“流”这种抽象概念。
字符设备可以通过文件节点来访问,比如/dev/tty1和/dev/lp0等。这些设备文件和普通文件之间的唯一差别在于对普通文件的访问可以前后移动访问位置,而大多数字符设备是一个只能顺序访问的数据通道。
ls -l看到的字符设备:类型为c
块设备
- 每个块设备在/dev目录下对应一个设备文件,linux用户程序通过设备文件(或称设备节点)来使用驱动程序操作块设备。
- 和字符设备类似,块设备也是通过/dev目录下的文件系统节点来访问。块设备(例如磁盘)上能够容纳filesystem。在大多数的Unix系统中,进行I/O操作时块设备每次只能传输一个或多个完整的块,而每块包含512字节(或2的更高次幂字节的数据)。
ls -l看到的块设备:类型为b
网络设备
特点
- 面向报文而不是面向流的,因此将网络接口映射到filesystem中的节点(比如/dev/tty1)比较困难。
- 内核调用一套和数据包相关的函数,而不是read,write。
- 网络接口没有像字符设备和块设备一样的设备号,只有唯一的名字,如eth0,eth1
- 主要通过socket操作,Unix访问网络接口的方法仍然是给它们分配一个唯一的名字(比如eth0),但这个名字在filesystem中不存在对应的节点。内核和网络设备驱动程序间的通信,完全不同于内核和字符以及块驱动程序之间的通信,内核调用一套和数据包相关的函数socket,也是套接字。
网络设备是特殊设备的驱动,它负责接收和发送帧数据,可能是物理帧,也可能是ip数据包,这些特性都有网络驱动决定。它并不存在于/dev下面,所以与一般的设备不同。网络设备是一个net_device结构,并通过register_netdev注册到系统里
任何网络事物都需要经过一个网络接口形成,网络接口是一个能够和其他主机交换数据的设备。接口通常是一个硬件设备,但也可能是个纯软件设备,比如回环(loopback)接口。
网络接口由内核中的网络子系统驱动,负责发送和接收数据包。许多网络连接(尤其是使用TCP协议的连接)是面向流的,但网络设备却围绕数据包的传送和接收而设计。网络驱动程序不需要知道各个连接的相关信息,它只要处理数据包即可。
使用ifconfig查看网络设备: