背景
继上一篇《CPU的重置和初始化》文章之后,这次就到了启动过程的第三步了,激活BIOS/UEFI。 这里就有很多疑问:
- BIOS和UEFI是什么?它们都有什么作用?两者又是什么关系?
- BIOS/UEFI存储在哪里?
- CPU是通过预设的起始地址去找到BIOS/UEFI的启动代码的,那这个地址是多少?为什么要用这个起始地址?
- CPU是怎么运行BIOS/UEFI的?
- 没有物理内存,光靠CPU能运行起来吗?
解析
1. 了解BIOS/UEFI
1.1 什么是BIOS
BIOS(Basic Input Output System,基本输入输出系统)是计算机上存储在非易失性存储器中的软件,是在计算机启动时最先被执行的软件。
1.2 什么是UEFI
UEFI(Unified Extensible Firmware Interface),即统一可扩展固件接口,是一种现代的固件接口标准,用于替代传统的BIOS(基本输入输出系统)。
- Unified:统一,为各种不同的计算机硬件平台提供一个共同的接口标准;
- Extensible:可扩展,指UEFI并不是一个封闭的系统,而是可以通过添加驱动程序和应用来扩展其功能的平台。这种扩展性使得UEFI能够支持新的硬件设备和技术,而无需等待UEFI固件本身的更新;
- Firmware Interface:固件接口,代表它是一种软件,嵌入在计算机的固件中,为操作系统和计算机的硬件提供一个接口。通过这个接口,操作系统能够在启动时通过固件层提供的服务与硬件进行交互;
1.3 BIOS/UEFI作用是什么
它们的主要作用是在操作系统接管计算机之前,初始化和测试计算机硬件系统,提供一组固定的低级接口,以便操作系统和应用程序与硬件设备交互。
1.4 两者的关系
其实上面已经讲过了,UEFI是用于替代传统的BIOS的。相对于BIOS,UEFI有许多改进和优势:
- 突破了启动盘大小限制:BIOS受限于MBR(主引导记录)分区表的约束,只能支持最大2TB的硬盘。UEFI使用GPT(GUID分区表)替代了MBR,理论上可以支持高达9.4ZB(亿TB)的硬盘;
- 更好看的图形用户界面:UEFI提供图形用户界面(GUI),使得配置过程更加直观和用户友好,相比之下,BIOS通常只提供文本界面;
PS:为什么BIOS通常只提供文本界面,你们可以去查查资料,跟计算架构有一定的关系。 - 支持安全启动:UEFI引入了安全启动(Secure Boot)功能,可以在启动过程中验证操作系统加载器的数字签名,防止恶意软件(如引导级的rootkits)篡改启动过程。只有经过签名的操作系统才能被允许启动,这大大提高了系统的安全性;
PS:谁是第一个获取到UEFI签名认证的国产系统呢?有兴趣的同学可以自己去查查。 - 强大的扩展性:UEFI固件可以加载第三方驱动程序和应用程序,这为硬件诊断、系统修复工具、操作系统安装器等提供了更大的灵活性。
1.5 小结
BIOS和UEFI是计算机启动过程中关键的固件组件,负责初始化硬件并为操作系统的加载做准备。BIOS是早期的系统,提供基础的输入输出支持,而UEFI作为其现代替代品,带来了多项改进,包括支持更大的硬盘、图形用户界面、安全启动等特性,同时UEFI的模块化和扩展性还允许更灵活地支持新硬件和技术。
2. 存储BIOS/UEFI固件媒介
我们在介绍BIOS的时候就说过,BIOS固件是存储在非易失性存储器中的,那这个非易失性存储器是什么媒介呢?
自奔腾时代起,现代计算机主板普遍采用闪存芯片来存储BIOS/UEFI固件代码,主要有两种类型的闪存:NOR Flash 和 NAND Flash。
它们的区别:
- NOR Flash:提供很好的随机读取性能,允许执行代码直接从Flash中运行(即XIP,执行原地),但写入和擦除操作速度相对较慢,成本也较高。
- NAND Flash:提供更高的数据密度和更快的写入速度,成本较低,但随机读取性能较差,不适合XIP应用。因此通常用于数据存储应用,如固态硬盘(SSD)、USB闪存驱动器等。
目前市场上众多现代主板使用的是NOR Flash来作为存储BIOS/UEFI固件代码的媒介。
3. 预设起始地址
这个地址通常是0xffff fff0。这个地址位于内存地址空间的顶端,确保CPU能够立即找到启动代码。那这个地址是怎么来的呢?
在计算机启动时,CPU的硬件设计确保代码段寄存器(CS)被预设为0xF000 ,而指令指针寄存器被设置为0xFFF0。这种设定是由CPU的设计固定的。但CPU内部使用的内存地址都是逻辑地址,所以需要转化为物理地址,上面两个寄存器预设值转化为物理地址就为CS=0xFFFF F000,PA=CS<<4+IP=0xFFFF FFF0。
4. 启动BIOS
在有了这个预设起始地址之后,CPU就开始寻址:
(1)CPU会将转换后的物理地址放到地址总线上;
(2)DMI(Direct Media Interface)控制器把该请求通过DMI总线发给南桥芯片组;
(3)南桥芯片组发现该地址被BIOS的ROM映射过;
(4)CPU就读到了写在BIOS ROM中的数据,该数据是一个远跳指令;
(5)该远跳指令具体跳到什么地址上是由BIOS厂商决定,地址空间范围肯定在[0xe 0000...0x10 0000];
(6)CPU从跳转后的地址开始执行BIOS程序。
这整个过程叫做Shadow(映射)。
5. XIP(Execute In Place)
这里大家可能还有一个问题,一般来说,CPU在执行程序的时候是需要内存的,但是在此阶段物理内存还未初始化,那BIOS程序为何能运行起来?
其实之前我们在讲存储BIOS/UEFI固件媒介时,就有提到一个关键词是XIP(Execute In Place) ,中文翻译位“原地执行”,什么意思呢?
它指的是一种程序直接从非易失性存储器(如闪存)执行,而不需要先复制到RAM中的方法。现代主板都是使用NOR Flash来作为存储BIOS/UEFI固件代码的媒介,它具备较快的读取速度和随机访问能力(字节寻址),所以CPU可以直接从NOR Flash中读取并执行代码,而不需要将代码预先加载到RAM(随机访问存储器)中。
还有一个关键概念是Cache As RAM(CAR) ,是指在主内存还未被初始化之前,可以暂时被用作快速存储空间,以支持CPU的基本运算和执行过程。虽然可以在特定情况下提供便利,但直接从非易失性存储执行代码(即XIP,Execute In Place)通常更为高效和直接。
所以,没有物理内存,BIOS也是可以运行起来的。
总结
- BIOS是计算机启动时最先被执行的软件,它的作用是初始化和测试计算机硬件系统,并提供一组固定的低级接口,以便操作系统和应用程序与硬件设备交互;UEFI是用于替代传统的BIOS的。
- 在计算机启动时,CPU通过预设的逻辑地址,转化为物理地址0xFFFFFFF0寻找BIOS/UEFI启动代码,这个过程叫做Shadow(映射);
- CPU能够读取存储在NOR Flash中的BIOS/UEFI固件,这是因为NOR Flash支持XIP(Execute In Place,原地执行),允许CPU直接执行存储器中的代码,而不需加载到RAM中。