包含linux设备驱动开发的基础知识及统信UOS设备驱动的总体架构,常用的设备驱动开发调试优化手段及在环境搭建和代码编写过程中常见问题处理等。
文章目录
基础知识
1. Linux设备驱动
概述
计算机系统的运转都是系统中软硬件共同努力的结果,硬件是底层基础,是所有软件得以运行的平台,代码最终会转换为硬件上的组合逻辑与时序逻辑。
软件分为系统软件和应用软件。系统软件核心也就是操作系统主要负责管理系统硬件资源,给应用软件提供访问系统硬件资源的接口和运行环境,有了系统软件支撑,应用软件可以聚焦用户业务需求而快速地完成设计。
设备驱动是操作系统内核重要组成部分,负责与底层硬件直打交道,按照硬件设备的设计原理,读写设备的寄存器,完成设备的轮询、中断处理、DMA 通信,进行物理内存向虚拟内存的映射等,最终让网络设备能收发数据,让显示设备能显示文字和画面,让存储设备能记录文件和数据。
设备驱动充当了硬件和应用软件之间的桥梁(如下图所示)。
设备驱动分类
Linux系统下的设备从不同角度有不同的分类描述。
从功能角度,分为输入设备、输出设备、显示设备、存储设备等,根据数据传输类型将设备驱动分为字符设备、块设备、网络设备。
字符设备的数据以字节流方式被系统读写,字节流就像在硬件端口和文件系统搭建起了一个传送管道, 字节逐个通过管道传输并呈现给读写双方。在Linux系统中,字符设备以文件方式在文件目录树中占据位置并拥有相应的设备结点。使用与普通文件相同的文件操作命令对字符设备文件进行操作,例如打开、关闭、读、写等。
块设备将信息存储在固定大小的块(block)中,每个块都有自己的地址,数据块的大小通常在512字节到32768字节之间。块设备只支持以块为单位的访问方式。,磁盘是最常见的块设备。
网络设备传输的数据是按照网络协议封装的数据包,网络子系统驱动负责数据包的发送和接收。对网络设备的访问是通过socket调用产生,网络设备驱动将上层协议传递下来的数据包以特定的媒介访问控制进行发送,并将接收到的数据包传递给上层协议。
Linux系统对网络设备驱动定义了四个层次,这四个层次为网络协议接口层、网络设备接口层、设备驱动功能层、网络设备与媒介层,如下图所示。
Linux网络设备驱动程序层次结构
Linux设备驱动框架
设备驱动是操作系统内核的一部分,是与具体硬件设备相关的软件逻辑,既可以静态编译进内核,也可以独立于内核编译成模块,在需要时动态加载进内核空间执行。
除了网络设备外,字符设备和块设备都被映射到文件系统的文件,体现了Linux一切皆文件的理念。
用户态程序通过文件系统的系统调用接口和驱动交互,整体框架如下图所示,
Linux设备驱动框架
总线、设备、驱动模型
Linux系统采用设备、总线、驱动的模型实现管理所有的物理设备。Linux引入了platform虚拟总线,管理那些物理上非总线连接的设备和虚拟设备。
Linux设备驱动模型
Linux的内核驱动以模块(以ko做后缀的文件)方式存在,当有新的设备通过电信号通知Linux系统插入时,Linux系统就将当前总线上注册的驱动都查询一遍,看是否有驱动匹配新接入设备。一旦硬件设备和设备驱动匹配成功,设备驱动就开始对硬件做探测初始化。当驱动完成所有的初始化操作,这个新接入的硬件设备在当前系统就是可用的。
2. 统信UOS设备驱动
UOS设备驱动框架
当前UOS的内核驱动基于linux驱动框架,通过DKMS提升扩展性增加对厂商设备驱动支持,同时支持同源异构,
总体架构如下图:
统信UOS设备驱动框架
内核版本维护策略
内核是UOS极其重要的组成部分,通用版本的内核采用上游的LTS版本,在此基础上面会合入国产CPU的补丁,并实现同源异构。
当前V20通用版本内核支持 4.19和5.10双内核,维护持续到V20的生命周期结束。每个内核版本对外发布一个KABI版本,整个生命周期内维护KABI whitelist不变。
4.19内核通过生态渠道获取
5.10内核可以通过github获取
https://github.com/deepin-community/kernel/tree/UOS-K5.10-LTS
KABI维护策略
为了满足 kernel 和 vendor module 厂商开发之间相互独立,我们需要在 kernel 和 vendor module 之间确定一个稳定的接口,这个就是 KABI。
KABI (Kernel Application Binary Interface) 兼容,即内核与驱动的二进制兼容。就是驱动无需重新编译,即可在新内核上安装使用。如果驱动用到的接口都是兼容的,那么驱动就可以不用重新编译就可以在新版本安装使用。
统信会基于目前所有二进制驱动,获取其涉及到的所有API形成清单,并确保该清单内的所有API,在Kernel变更时不受影响。
3. DKMS介绍
Dynamic Kernel Module Support(DKMS)是一个用于动态管理内核模块的框架,由DELL创建的项目,它可以帮我们维护内核