前言
本篇文章主要为大家简要地介绍一下Linux驱动以及学习Linux驱动的基本方法。
一、什么是驱动
1、理解驱动的概念
(1)驱动一词的字面意思:用动力推动,施加外力,使动起来
(2)硬件中的驱动:电源类设备,比如电源就是一个驱动,驱动led照明,供电
(3)linux内核驱动。软件层面的驱动广义上就是指:这一段代码操作了硬件去动,所以这一段代码就叫硬件的驱动程序。(本质上是电力提供了动力,而驱动程序提供了操作逻辑方法)狭义上驱动程序就是专指操作系统中用来操控硬件的逻辑方法部分代码。
裸机驱动:裸机用来操作硬件的那部分代码。
2、linux体系架构
应用 -> API/C库函数 -> 操作系统内 -> 驱动
(1)具有分层思想
(2)驱动的上面是系统调用API
(3)驱动的下面是硬件(通过操控一系列的寄存器来操控硬件)
(4)驱动自己本身也是分层的
二、模块化设计
1、微内核和宏内核(操作系统的两种不同设计)
(1)宏内核(又称为单内核):将内核从整体上作为一个大过程实现,并同时运行在一个单独的地址空间。所有的内核服务都在一个地址空间运行,相互之间直接调用函数,简单高效。(所有文件编译生成一个可执行程序,这样的内核是紧耦合的)
(2)微内核:功能被划分成独立的过程(驱动程序,文件系统程序,进程调度程序等等),过程间通过IPC进行通信。模块化程度高,一个服务失效不会影响另外一个服务。有多个功能模块,典型如windows
(3)linux:本质上是宏内核,但是又吸收了微内核的模块化特性,体现在2个层面
静态模块化:在编译时实现可裁剪,特征是想要功能裁剪改变必须重新编译
动态模块化:zImage可以不重新编译烧录,甚至可以不关机重启就实现模块的安装和卸载。
三、linux设备驱动分类
1、驱动分类
(1)分3类:字符设备驱动、块设备驱动、网络设备驱动
(2)分类原则:设备本身读写操作的特征差异,硬件决定软件的编写
2、三类驱动程序详细对比分析
(1)字符设备,准确的说应该叫“字节设备”,软件操作设备时是以字节为单位进行的。典型的如LCD、串口(一个一个字节的去读或者去发送)、LED(读写寄存器也是以字节为单位操作的)、蜂鸣器、触摸屏······
(2)块设备,块设备是相对于字符设备定义的,块设备被软件操作时是以块(多个字节构成的一个单位)为单位的。设备的块大小是设备本身设计时定义好的,软件是不能去更改的,不同设备的块大小可以不一样。常见的块设备都是存储类设备,如:硬盘、NandFlash、iNand、SD····
想将某个字节的a改成b,必须将整个块读取到内存中,找到这个字节,将这个字节修改(在内存中可以以字节为单位访问),然后将整个块的内容再写入到块设备中。
(3)网络设备,网络设备是专为网卡设计的驱动模型,linux中网络设备驱动主要目的是为了支持API中socket相关的那些函数工作。
3、为什么字符设备驱动最重要
(1)常见大量设备都属于字符设备
(2)举例说明非标准类型字符设备驱动
例如操空fpga
非标准化设备一般都会实现为字符设备。
usb优盘既可以实现为块设备,也可实现为字节设备。
五、驱动程序的安全性要求
1、驱动是内核的一部分
(1)驱动已经成为内核中最庞大的组成部分
(2)内核会直接以函数调用的方式调用驱动代码
(3)驱动的动态安装和卸载都会“更改”内核
2、驱动对内核的影响
(1)驱动程序崩溃甚至会导致内核崩溃
(2)驱动的效率会影响内核的整体效率(以字节为单位读写还是以块为单位读写)
(3)驱动的漏洞会造成内核安全漏洞
3、常见驱动安全性问题
(1)未初始化指针,非法访问
(2)恶意用户程序
(3)缓冲区溢出,应用传给驱动的参数过多,覆盖掉有用的数
据
(4)竞争状态(自旋锁,互斥锁)
六、驱动应该这么学
1、先学好C语言
2、掌握相关预备知识
(1)硬件操作方面
(2)应用层API
3、驱动学习阶段
(1)注重实践,一步一步写驱动
(2)框架思维,多考虑整体和上下层
(3)先通过简单设备学linux驱动框架
(4)学会总结、记录,这会有助于理解
注:本资料大部分由朱老师物联网大讲堂课程笔记整理而来,如有侵权,联系删除!水平有限,如有错误,欢迎各位在评论区交流。