简单来讲,固件、驱动程序和软件之间的根本区别在于它们的设计目的。

  • 固件是赋予设备硬件生命的程序
  • 驱动程序是操作系统和硬件组件之间的中间人
  • 软件可以间接操作硬件

1. 固件

固件(Firmware)就是写入 ROM (只读存储器)中的程序,固件担任着一个系统最基础最底层工作,直接控制硬件,比如计算机上电后第一个启动的程序 BIOS ,它可以与硬件交互,并检查它是否有任何错误。

BIOS 调用另一个称为引导加载程序的程序,该程序执行唤醒在硬盘驱动器内休眠的操作系统并将其放入随机存取存储器 (RAM) 的工作。

我们可以在许多设备上看到固件,包括计算机、手机、遥控器、游戏机、智能手表、USB 驱动器和各种嵌入式系统。即使是电视遥控器也有一个预装的固件,可以实现你按下按钮的时候电视换台操作。

2. 驱动

驱动(Drive):驱动程序即添加到操作系统中的一小块代码,其中包含有关硬件设备的信息。当计算机程序请求与某个硬件设备交互时,设备驱动程序充当硬件设备与使用它的程序之间指令的转换器。

操作系统并不支持机器上的所有硬件,所以一般来讲硬件厂商都要为自己的硬件编写驱动程序。

每个驱动程序都旨在为特定或一组设备工作。在计算机上,驱动程序使用各种总线接口来联系设备。此外,驱动程序一般不直接与用户交互,所以很多用户完全不知道它们的存在。

驱动程序的开发需要非常小心,因为它直接与硬件打交道,同时也与操作系统打交道。如果设备驱动程序出现问题,可能会导致系统崩溃,这就是为什么需要专业人员或团队来为设备编写驱动程序的原因。

但是为什么不把 Firmware 做的很完美,做的不需要驱动支持呢?因为有不同的操作系统,而这些操作系统对于操作硬件的方式完全不同。所以不同操作系统的驱动是不能兼容的,原因就是驱动是为操作系统服务的。


固件:Firmware. 就是写入EROM(可擦写只读存储器)或者EEPROM(电可茶歇可编程只读存储器)中的程序

固件是只设备内部保存的设备“驱动程序”,通过固件,操作系统才能按照标准的设备驱动实现特定机器的运行运作,比如光驱,刻录机等都有内部固件。

固件是担任着一个系统最基础最底层工作的软件。而在硬件设备中,固件就是硬件设备的灵魂,因为一些硬件设备除了固件以外没有其他软件组成,因此固件也就决定这硬件设备的功能以及性能。

手机、数码相机、mp3、mp4、路由器、电子书、交换机、猫、PSP、PS3、NDS、XBOX、U盘、主板、打印机的BIOS(BIOS就是一种固件)、显卡的BIOS。

固件既然是软件,就有大小之分。大的可有几百兆,小的也许只有几K,甚至不足1K。

而对于非独立的电子产品,比如硬盘、鼠标、BIOS、光驱、U盘等设备,固件就是指其最底层的,让设备得以运行的程序代码。


固件与驱动的区别:

驱动和固件(firmware)都是代码,前者为软件服务,后者为硬件服务。

随着计算机体系结构的发展,硬件的种类开始变多,操作系统的种类也变多了。
这个时候,因为各种技术的、商业的原因,硬件厂商希望自己的硬件能被更多的软件厂商使用,所以就需要在硬件之上做一些封装,让自己的硬件操纵起来更容易,这个时候就要有firmware这种东西了,它简化了软件与硬件的交互。

但是为什么不把fimware做的很完美,做的不需要驱动支持呢?因为有不同的操作系统。

不同的操作系统,对于操作硬件的方式完全不同,在Windows里应用态是无法直接写IO端口的,而在嵌入式系统里,一般都不限制直接操作IO端口。所以,硬件厂商一方面为了自己的硬件能被软件更简单的使用,就需要写firmware,而另一方面为了兼容各种操作系统,又不能把firmware写的太死,必须预留足够的余地让软件自由发挥——软件的自由发挥就是驱动。

不同操作系统的驱动是不能兼容的,原因就是驱动是为操作系统服务的,有的操作系统是单线程的,有些操作系统不允许动态申请内存,所以不同的操作系统要操作硬件,就要根据自身的特性编写对应的操作代码,这就是驱动存在的意义——适应系统需要。

假如世界上只有一种操作系统,并且版本永远不会改变,那么firmware和驱动就可以融合在一起,但这只能一个不现实的梦想,要知道民用操作系统和工业控制操作系统差别是十分巨大的。

从计算机领域来说,驱动和固件从来没有过明确的定义,就好像今天我们说内存,大部分人用来表示SDRAM,但也有人把Android里的“固化的Flash/Storage"称为“内存”,你不能说这样说就错了,因为这确实是一种“内部存储”。
但在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和firmware没有什么直接的关系。


相同点都是管理硬件的,区别是随谁一起发布。随硬件一起发布的叫固件,随软件一起发布的叫驱动。

随硬件一起发布是因为没有固件,硬件本身无法工作,如bios。随软件一起发布是因为为没有它软件无法在目标硬件上工作,如linux驱动。说白了只看出身立场,不看能力。

软件厂商和硬件厂商之间有一个接口界面,这个界面下的软件通常叫firmware,由硬件厂商提供,之上的操作硬件的叫驱动,有软件厂商提供。这个界面可以是大家一起订立的,也可以是软件厂商定义的,也可以是硬件厂商定义的。硬件厂商定义的话,通常倾向于把界限网上推,这样他能干更多的事情,能对软件友好,从而提高市场占有率。软件厂商定义的话,倾向于往下推,这样它可以要求硬件厂商开放更多硬件信息,软件可以做更多优化。通常的结果是大家定义一个最合适的界限,然后都想越过这个界限。比如说uefi,它做了很多驱动做的事情,试图取代驱动。而linux内核也不肯放弃驱动,所以选择不使用uefi提供的好多功能。


驱动和固件其实非常好区分,我一说你就能明白。

驱动Driver是“中间件”,为上提供API,下接硬件或者软件服务(如数据库)。

固件Firmware则是完整的软件封装,小到控制鼠标,大到控制一个运动控制系统。

我们一般说的狭义上的驱动,都是运行在操作系统上,提供编程或系统接口的。嵌入式无操作系统下,驱动的概念同样存在,这时驱动表示对外提供API的软件封装:比如SPI驱动、IIC驱动、IO外设驱动、传感器等。


这个要从Vxworks说起。因为BSP的概念好像就是从它提出的而来。BSP顾名思义,板级支持包,主要作用就是初始化硬件,引导系统和驱动。在这个过程中,固件的主要作用就是Init,说到这里是不是感觉跟我们常用的PC主板上面的BIOS很像?其实,它们都是一个东西,只不过是不同硬件平台上不同的叫法而已。再比如,小时候你玩的那个FC红白机的游戏卡以及一般计算器主板上面是不是有一个黑黑的一个圆盘样的玩意儿?所有游戏数据都在里面,这种低端电子产品里面的牛屎芯片写入的都算是固件。说到这里是不是明白了固件它的作用就是Init,Init自然是要初始化硬件的,初始化硬件肯定要调用硬件接口,调用接口自然要加载设备驱动了。所以,回到正题。固件是初始化基本硬件的一段程序,驱动是调用硬件接口的一段程序;所以驱动是固件功能上的一个子集(这个与PC没有矛盾,PC上面的BIOS只负责主板初始化,不负责外部设备)。