概述
固件
固件(Firmware)就是写入EPROM(可擦写可编程只读存储器)或EEPROM(电可擦可编程只读存储器)中的程序。
固件是指设备内部保存的设备“驱动程序”,通过固件,操作系统才能按照标准的设备驱动实现特定机器的运行动作,比如光驱、刻录机等都有内部固件。比如计算机主板上的基本输入/输出系统BIOS(Basic Input/output System),在以前其实更多的专业人士叫它固件。
固件是担任着一个系统最基础最底层工作的软件。而在硬件设备中,固件就是硬件设备的灵魂,因为一些硬件设备除了固件以外没有其它软件组成,因此固件也就决定着硬件设备的功能及性能。
固件是担任着一个系统最基础最底层工作的软件。而在硬件设备中,固件就是硬件设备的灵魂,因为一些硬件设备除了固件以外没有其他软件组成,因此固件也就决定这硬件设备的功能以及性能。
驱动
驱动就是一段程序,能够获取外设或者传感器数据、控制外设。驱动获取到的数据会提交给应用程序。
在 Linux 中一切皆为文件,驱动加载成功以后会在“/dev”目录下生成一个相应的文件,应用程序通过对这个名为“ /dev/xxx ”的文件进行相应的操作即可实现对硬件的操作。 比如 /dev/ttyS2 表示串口设备,应用程序可以调用 read 函数从设备中读取数据,可以调用write函数向设备写入数据。
表面上是应用程序在操作设备,实际上这个过程中有驱动的参与。
中间件
**中间件是一类连接软件组件和应用的计算机软件,它包括一组服务。以便于运行在一台或多台机器上的多个软件通过网络进行交互。**该技术所提供的互操作性,推动了一致分布式体系架构的演进,该架构通常用于支持并简化那些复杂的分布式应用程序,它包括web服务器、事务监控器和消息队列软件。
固件与驱动的区别
不同的操作系统,对于操作硬件的方式完全不同,在Windows里应用态是无法直接写IO端口的,而在嵌入式系统里,一般都不限制直接操作IO端口。所以,硬件厂商一方面为了自己的硬件能被软件更简单的使用,就需要写firmware,而另一方面为了兼容各种操作系统,又不能把firmware写的太死,必须预留足够的余地让软件自由发挥——软件的自由发挥就是驱动。
不同操作系统的驱动是不能兼容的,原因就是驱动是为操作系统服务的,有的操作系统是单线程的,有些操作系统不允许动态申请内存,所以不同的操作系统要操作硬件,就要根据自身的特性编写对应的操作代码,这就是驱动存在的意义——适应系统需要。
在Linux Kernel中,Driver和Firmware是有明确含义的,其中Driver是控制被操作系统管理的外部设备(Device)的代码段。很多时候Driver会被实现为LKM,但这不是必要条件。driver通过register_dirver()注册到总线(bus_type)上,当某个device被注册到同样的总线的时候,driver和device会通过一定的策略进行binding,最终在probe()函数中由driver实际控制对应的设备,并把对该设备的控制接口注册到Linux的其他子系统上(例如字符设备,v4l2子系统等)。
而Firmware,是表示运行在非“控制处理器”(指不直接运行操作系统的处理器,例如外设中的处理器,或者被用于bare metal的主处理器的其中一些核)中的程序。这些程序很多时候使用和操作系统所运行的处理器完全不同的指令集。这些程序以二进制形式存在于Linux内核的源代码树中,根据配置,可以直接集成到最终的映像中,或者被拷贝到指定的位置。当driver对device进行初始化的时候,通过load_firmware()等接口,可以把指定的firmware加载到内存中,由驱动传输到指定的设备上。
Driver
应用程序调用驱动的基本流程
file_operations 结构体
file_operation就是把系统调用和驱动程序关联起来的关键数据结构。这个结构的每一个成员都对应着一个系统调用。读取file_operation中相应的函数指针,接着把控制权转交给函数,从而完成了Linux设备驱动程序的工作。
在系统内部,I/O设备的存取操作通过特定的入口点来进行,而这组特定的入口点恰恰是由设备驱动程序提供的。通常这组设备驱动程序接口是由结构file_operations结构体向系统说明的,它定义在include/linux/fs.h中。
注册设备编号仅仅是驱动代码必须进行的诸多任务中的第一个。大部分的基础性的驱动操作包括 3 个重要的内核数据结构,称为: file_operations、file、和 inode。
- struct file_operations是一个字符设备把驱动的操作和设备号联系在一起的纽带,是一系列指针的集合,每个被打开的文件都对应于一系列的操作,这就是file_operations,用来执行一系列的系统调用。
- struct file代表一个打开的文件,在执行file_operation中的open操作时被创建,这里需要注意的是与用户空间inode指针的区别,一个在内核,而file指针在用户空间,由c库来定义。
- struct inode被内核用来代表一个文件,注意和struct file的区别,struct inode 代表文件,struct file 代表打开的文件。
驱动分类
常见三类:
- 字符型设备驱动:只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后顺序。常见的字符设备有鼠标、键盘、串口、控制台和LED设备。
- 块设备驱动:可以从设备的任意位置读取一定长度数据的设备。块设备包括硬盘、磁盘、U盘和SD卡等存储类设备。
- 网络设备驱动:负责读写来自网络的数据。常见的网络设备有网卡(有线、无线)。
注
原文出处:
- https://www.jianshu.com/p/0222686c0fb4
- https://blog.youkuaiyun.com/challenglistic/article/details/131021431
- https://blog.youkuaiyun.com/monkea123/article/details/126527018