0%

谈谈BIOS

DEV!

0x00 前言

今天玩了一点,加上微原讲过一点,DEV组会也说了BIOS的事情,就总结一下。

为了启动操作系统,必须配置与对应操作系统兼容的引导加载程序

引导加载程序负责在初始化启动进程之前,加载好内核和(初始RAM文件系统),具体过程因系统相异。

0x01 固件类型

BIOS

Basic Input-Output System:[初始化] 和 [加电自检]。

通过 [初始化] 和 [加电自检],并将硬件封装为BIOS中断服务。这样一来,各种硬件之间的差异都由BIOS负责维护,程序直接调用 [BIOS中断服务] 即可实现对硬件的控制。

最初的BIOS都是在ROM里的程序代码,现在的BIOS都在闪存芯片上,独立于其它系统存储,方便BIOS更新。

从 2010 年起已逐渐被技术上不受限的 UEFI 替换。

UEFI

统一可扩展固件接口Unified Extensible Firmware Interface,UEFI)是用来定义 [OS] 与 [系统固件] 之间的软件界面,作为BIOS的一种替代方案,支持读取分区表和文件系统,在概念上类似一个低阶的操作系统。

可扩展固件接口负责加电自检(POST)、联系操作系统以及提供连接操作系统与硬件的接口。

UEFI启动过程只依赖非易失性随机访问存储器(NVRAM)中的引导条目。

UEFI规范要求支持 FAT分区 中的文件,即:FAT12、FAT16、FAT32文件系统。

✍由于历史原因,UEFI也被习惯叫做BIOS。

0x02 BIOS与UEFI的启动过程(了解BIOS即可)

现在你按下了电脑开机键,系统上电:

启动本质三步

1. Rom Stage: 在这个阶段 [没有内存] ,需要在 [ROM] 上运行代码。这时因为没有内存,没有C语言运行需要的栈空间,开始往往是汇编语言直接在ROM上运行。在找到个临时空间(Cache空间用作RAM,Cache As Ram, CAR)后,C语言终于可以登场了,后期用C语言初始化内存和为这个目的需要做的一切服务。

2. Ram Stage: 在经过 ROM阶段的困难情况后,我们终于有了可以大展拳脚的内存,很多额外需要大内存的东西可以开始运行了。在这时我们开始进行初始化芯片组、CPU、主板模块等等核心过程。

3. Find Something to Boot Stage: 进入正题:需要启动。我们找到启动设备,就要枚举设备,发现启动设备,并把启动设备之前需要依赖的节点统统打通。

BIOS

CPU运行于 [实模式] 工作环境中,数据位宽为16位,最大物理地址寻址范围是1MB,CPU首先跳到 处执行程序,一般情况下这里是一条跳转指令,CPU根据这个跳转指令跳到真正的BIOS入口地址执行。

1.加电自检(POST,Power On Self Test),检测 [关键设备] 是否正常工作,如果有故障,喇叭就会叫唤。

2.初始化 [显示设备] 并显示显卡信息。

3.检测 [CPU和内存] 并显示检测结果。

4.检测 [标准设备],如硬盘、光驱、串口设备、并口设备等。

5.检测 [即插即用设备],并为这些设备分配 中断号、I/O端口和DMA通道 等资源。

6.如果硬件配置发生变化,那么这些变化的配置将更新到 CMOS 中。

7.根据配置的启动顺序引导设备启动,通过BIOS中断将设备的引导程序读入内存。

8.将处理器的控制权交给引导程序,最终引导进入操作系统。

UEFI(看看就行)

1.验证阶段(Security,SEC)。系统上电后,CPU开始执行第一条指令,此时系统就进入SEC阶段。这个阶段的内存尚未被初始化,不可使用。所以,SEC阶段最主要的工作是 [建立一些临时内存并将CPU切换到保护模式] ,这里提到的临时内存可以是处理器的缓存,亦或者系统的物理内存。

2.EFI环境预初始化阶段(Pre-EFI Initialization Environment,PEI)。PEI阶段最主要的工作就是对内存、CPU以及芯片组等关键设备进行初始化。由于这部分代码没有进行压缩,因此代码必须越精简越好。而且,在PEI阶段还要确定操作系统的引导路径,初始化UEFI驱动和固件需要的内存。

3.驱动运行环境阶段(Driver Execution Environment,DXE)。DXE是EFI最重要的阶段,大部分的驱动、固件加载工作都是在这个阶段完成的。

4.引导设备选择阶段(Boot Device Select,BDS)。BDS阶段的主要工作是初始化控制台设备的环境变量,尝试加载环境变量列表中记录的驱动,并尝试从环境变量列表中记录的启动设备中启动。

5.临时系统运行阶段(Transient System Load,TSL)。这个阶段将进入UEFI的临时Shell系统环境。

6.运行时阶段(RunTime,RT)。当操作系统调用EFI_BOOT_SERVICES.ExitBootServices服务后,系统进入RT阶段。此时,DXE与引导服务都将销毁,只有EFI运行时服务和EFI系统表可以继续使用。

7.后世阶段(After Life,AL)。当操作系统调用EFI_RUNTIME_SERVICES.ResetSystem服务或者调用ACPI Sleep State,系统进入AL阶段。触发异步事件(比如:SMI、NMI)亦可使系统进入AL阶段,这在服务器和工作站中比较常见。

0x03 BIOS与UEFI的比较

关于BIOS和UEFI二者的比较,如果仅从系统启动原理方面来做比较,UEFI之所以比BIOS强大,是因为UEFI本身已经相当于一个微型操作系统,以下将解释UEFI相比BIOS的优点:

首先,UEFI已具备文件系统的支持,它能够直接读取FAT分区中的文件。

其次,可开发出直接在UEFI下运行的应用程序,这类程序文件通常以efi结尾。

UEFI能管理文件,还有能在UEFI下运行的.efi文件,那么就可以把win10做成.efi文件放到FAT分区直接运行,就像win10运行QQ.exe那样简单。

Last but not least,上面这些BIOS都做不到,BIOS启动操作系统 [必须从硬盘上指定扇区读取启动代码,然后从活动分区引导启动OS],对于扇区的操作远不如UEFI直观简洁。

UEFI和BIOS在对硬件检测的流程是一样的,但最大区别的是对后续的系统影响不一样,就用制造来比喻:

UEFI/BIOS跟操作系统是两个工序,UEFI/BIOS是前工序,操作系统是后工序,UEFI对比BIOS要多出一个流程:形成交接文件;BIOS是该我工作的部分(自检)我一个不落的完成,但我把我完成的东西就扔给操作系统,但操作系统完全不知道前一工序的状态,还得重新做一篇检查,而UEFI就是把自己检测好的状态写进文件,告诉操作系统这些东西没问题,你就放心启动吧,不用再次检查了。

BIOS缺点

开发效率低:汇编语言开发/代码与设备耦合度太高,受硬件变化的影响大

性能差:需要通过中断来完成,开销大,BIOS还没有异步工作模式

功能拓展差:静态链接,且必须将代码放到对应内存位置,没有动态加载设备驱动的方案

安全性:没有对安全性的考虑

地址空间:不支持32位地址以上

UEFI优点

👍开发效率高:C语言编写,屏蔽底层细节

👍拓展性高:驱动都是模块化设计;每个表和协议都有版本号,系统升级更平滑;磁盘容量大

👍性能高:提供异步操作;放弃中断的方式(只保留时钟中断)

👍安全性:利用数字签名来确认EFI驱动程序或者应用程序是否是受信任的。

0x04 补充

Windows下最准确的判断方式:

①win+R cmd

②运行msinfo32.exe

-------------本文结束感谢您的阅读-------------
请作者喝一杯蜜雪冰城吧!