1.Legacy BIOS
Legacy BIOS是传统的BIOS,传统的BIOS直到x86_64架构还有在使用的,原因是向下兼容。BIOS使用16位的汇编代码、寄存器参数调用、静态链接、在1MB以下内存固定编址。在各大BIOS厂商的努力下,BIOS扩展了很多功能,如PnP BIOS、ACPI、USB设备支持等,但根本性质没有变。
BIOS下的设备驱动的执行方式是使用中断向量和固定大小的中断服务空间,典型的一个中断服务只有128KB的空间,也就是驱动大小不能超过128KB,并且驱动也都是以16位的形式编写和存在的。
2.EFI BIOS
现在的主板上基本都是EFI BIOS了,之所以不需要向下兼容的之前的BIOS,是因为EFI BIOS是在一个全新的架构(Itanium)下设计出来的,没有兼容问题。EFI(Extensible Firmware Interface,可扩展固件接口)的实现使用了C语言,所以就有堆栈、模块化、动态库等能力,软件工程带来的纠错性和可修改性特性缩短了开发时间,并且不再是只有16位的寻址能力,而是拥有32位或64位的寻址能力,能够达到处理器的最大寻址,也就是可以使用很多的内存了。其他的BIOS厂商也曾经视图取代BIOS,但是由于力量分散,厂家太多,无法形成统一的标准,然而EFI由Intel主推,已经逐步掌握整个市场。
与传统BIOS不同,EFI上的设备驱动不是由汇编写成的,也不是由C语言写成的,而是EFI的虚拟指令集。如此就保证了驱动的CPU无关性,即无论是志强还是安腾的CPU,同样的驱动代码都可以检测到正常的设备,不需要重新编译。这样可复用的开发模式使得EFI可以在不启动操作系统前就访问网络,甚至浏览网页。其可扩展性和可复用性带来的好处就是对于EFI系统的任何一次开发,都可以长久地被复用。
但是这不是EFI可以实现一个完整操作系统的理由。EFI的设计者故意使EFI没有实现一个操作系统的可能性。例如不支持中断,所有的硬件状态都是通过轮询完成的,并且其驱动代码是解释执行的。EFI上可以实现程序,但是所有程序都具有所有硬件的完全访问权限。所以,EFI注定只是一个启动前的过渡,启动完成后就会将主动权交给操作系统,自己的大部分功能停止运行。
3.UEFI
EFI是由Intel发起的,UEFI是之后发展的产物,由国际组织Unified EFI Form运行。这个组织除了Intel外还有很多其他的公司,所以有了前面的U字母。想要推动一个基础协议架构,若没有多个巨头的参与,一般情况下是推不动的。UEFI在EFI的基础上提供了图形化的操作界面,使用鼠标操作,我们也能在比较新的主板上看到这种操作方式。
ROM系统和Bootloader之间需要一种约定的调用规则。因为固件放在ROM中,开机后是会固定执行的,但Bootloader的代码却是放在磁盘(或其他存储设备)中的,需要从磁盘中加载。而在磁盘中组织数据的方式是文件系统,Bootloader或者内核的主体应该放在文件系统中。
当固件看到一个磁盘,发现了其拥有该磁盘的驱动,也就是拥有了读写该磁盘的能力后,接下来应该获取的信息是本磁盘的分区情况。磁盘的第一个字节就是可执行代码,然而这部分代码并不位于文件系统中。在传统的MBR磁盘格式中,前512字节存储了一些启动代码和整个磁盘的分区表。但是限于大小的原因,一个MBR只能支持4个分区。随着技术的发展,人们在单个分区的开头部分又实现了级联的分区表,启动软件也都能够陆续识别。但是存放启动文件的根目录必须位于主MBR上的分区。主MBR上的分区叫作Primary Partition(主分区),级联分区叫作逻辑分区(Logical Partition)。使用这个命令可以读取到MBR的二进制,根据结构定义就可以详细查看MBR的结构。如下所示。
然而MBR的这种定义,包括其较小的表示容量的位数,限制了每个分区的大小和可以支持的分区总数。随着EFI的推出,同时新的替代方案GPT也出现了。传统MBR信息存储于LBA 0(逻辑块),GPT头存储于LBA 1,接下来才是分区表本身。64位的Windows操作系统使用16,384字节(或32扇区)作为GPT分区表,接下来的LBA 34是硬盘上第一个分区的开始。GPT这样空出LBA 0,MBR的兼容性就得到了保障。一个磁盘设备(sdc)的GPT头部,如图4-1所示。
图4-1
一个GPT分区表项的前16个字节是分区类型GUID。例如,EFI系统分区(存放模块代码)的GUID类型是{C12A7328-F81F-11D2-BA4B-00A0C93EC93B}。接下来的16字节是该分区唯一的GUID(这个GUID指的是该分区本身,而之前的GUID指的是该分区的类型)。再接下来是分区起始和末尾的64位LBA编号,以及分区的名字和属性。
MBR分区表又叫作MSDOS分区表(出于历史原因)。还有两种不太常用的分区表是SGI和SUN分区表,一般只用在对应公司的平台上。