来自朱有鹏物联网大讲堂的学习笔记
驱动应该怎么学
(1)重点应该放在 字符设备驱动上面,它主要应对于 非标准件
(2)LED、蜂鸣器、framebuffer、input子系统、触摸屏等等都是 标准件,这些标准件主要是针对于它的 移植。
一、什么是驱动
1、理解驱动的概念
别问人,怎么答?
(1)驱动一词的字面意思
让一个物体动力,让他动起来,比如足球用人的脚踢起来,马车怎么动(马来进行驱动)
(2)硬件当中的驱动
比如电源模块,用来给设备提供能量。(比如 led 的电源模块,就叫做led 的驱动)
(3)Linux的内核驱动
裸机:没有操作系统,严格来说没有驱动这个概念,广义上来说也是有驱动。就是裸机当中控制硬件动的代码,就叫做驱动代码。
操作系统:严格来说驱动是依附于 linux 内核的,专门是操作系统当中用来操控硬件的逻辑方法部分代码。
(操作系统:进程管理、内存管理、文件系统、IO子系统(驱动))
2、linux 的体系架构
(1)分层思想
(2)驱动本身也是分层的
二、模块化设计
1、微内核和宏内核
(1)宏内核:单内核,将内核从整体上作为一个大过程实现,并同时运行在一个单独的地址空间。所有内核服务可以互相调用各个函数,简单高效。
(比如文件系统,直接调用驱动的函数。)
优点:简单高效
缺点:耦合性强,比如更换硬盘、就得更改驱动、更改文件系统的函数。
(2)微内核:功能被划分成独立的过程,(内存管理、进程管理这些模块的代码分开存放),进程之间通过 IPC
进行通信。典型就是 windows。
优点:模块化程度高、一个服务失效不会影响另外一个服务。
缺点:效率低。
(3)Linux :本质上是一个宏内核、但是又吸收了微内核的模块化特性。
模块化:在下面两个层面,来进行体现。
2、静态模块化
在编译的时候,实现功能可裁剪。
特征:想要功能的裁剪和改变,必须重新编译(体现出了静态的特点,并不是运行当中实现裁剪)。
3、动态模块化
zImage 可以不重新编译、甚至可以不关机重启,就可以实现模块的安装和卸载。
三、linux 设备驱动分类
按照针对设备的读写操作特征的差异来区分的。
本质:读写硬件的寄存器
(1)字符设备:
又叫做字节设备、按照一个字节一个字节,来进行操作。
LCD:有一块显存,将像素点按照一个字节来填写。
写LCD:将一个字节数据放到显存当中,硬件自动对应显示。
串口:一个字节、一个字节的去读、去写。
写串口:将一个字节写入寄存器,硬件自动发送。
读串口:读取串口的某个特定寄存器,硬件自动接收。
蜂鸣器:
触摸屏:
读:读取按下的坐标
(2)块设备:
相对一字符设备定义的,块设备被软件操作的时候,以块为单位操作的。(块可能是 256 字节,可能是 512 字节,由硬件决定)
比如:我们想要读取块设备当中的 1个字节,这时候我们必须至少读取 512 个字节,然后将剩余的 511 个字节数据丢弃。
常见的块设备都是存储类型的设备:硬盘、NandFlash、iNand 、 SD卡 等等。
(3)网络设备:
网络设备是专门为了网卡设计的模型,网络通信具有一套专有的接口,Linux 中网络设备驱动主要是为了支持 API 中 socket
相关的那些函数工作。
为什么说字符设备驱动最重要?
(1)常见大量设备都属于字符块设备
(2)而且有很多为非标准类型的设备,被实现为字符设备驱动
四、驱动程序的安全性要求
1、驱动是内核的一部分
(1)驱动已经成为内核中最庞大的组成部分(占到了 1/3 )
(2)内核会以函数调用的方式调用驱动代码。(宏内核)
(3)驱动的动态安装和卸载,都会更改内核。
2、驱动对内核的影响
(1)驱动程序奔溃,甚至会导致内核奔溃。也有可能不会跟着奔溃,因为 Linux 内核当中采用了模块化的设计。
(2)驱动的效率,会影响内核的整体效率。比如一个块设备,我们采用了一个字符设备驱动,然后影响到系统调用的效率,继续影响 API 的效率,最终影响应用程序的效率。
(3)驱动的漏洞,会造成内核安全泄漏。
3、常见驱动安全性问题
(1)未初始化的指针
(2)恶意用户程序:
(3)缓冲区溢出:
比如我们驱动程序当中有一个 buffer ,用来接收应用程序传输的设备,buffer 大小为 50个字节,结果有程序放了 10000个字节,那么就会造成通讯失效。
(4)竞争状态
五、驱动应该这么学
1、先学好C语言
2、掌握相关的预备知识
(1)硬件操作方面
(2)应用层 API
3、驱动学习阶段
(1)注重实践,一步一步写驱动。
(2)框架思维,多考虑整体和上下层。
(3)先通过简单设备学 Linux 驱动框架。
(4)学会总结、记录,有助于理解。