type
status
date
slug
summary
tags
category
icon
password
URL
从首次运用于Intel 安腾处理器,到第一版统一的可扩展固件接口(UEFI)规范出版,无论是在高性能服务器,移动设备或是深度嵌入式设备等,UEFI已在所有平台完全淘汰了BIOS。UEFI的成功离不开行业支持的开源实现以及行业指导平台固件规范。UEFI因其开放标准的特性,确保了它可以获得来自整个行业的广泛支持和投资的同时也推进了整个行业的技术变革。
一、UEFI与BIOS
要详细了解UEFI,还得从BIOS讲起。我们都知道,每一台普通的电脑都会有一个BIOS,用于加载电脑最基本的程式码,担负着初始化硬件,检测硬件功能以及引导操作系统的任务。UEFI就是与BIOS相对的概念,这种接口用于操作系统自动从预启动的操作环境,加载到一种操作系统上,从而达到开机程序化繁为简节省时间的目的。传统BIOS技术正在逐步被UEFI取而代之,在最近新出厂的电脑中,很多已经使用UEFI,使用UEFI模式安装操作系统是趋势所在。
主要是由于安腾处理器芯片组的创新,64位架构的处理器已经不再适用于传统BIOS的16运行模式,因此intel将系统固件和OS的接口完全重新定义成一个可扩展、标准化的固件接口规范。
UEFI: 统一可扩展固件接口(Unified Extensible Firmware Interface,UEFI),是一种详细描述全新类型接口的标准,是适用于电脑的标准固件接口,旨在代替BIOS(基本输入/输出系统)。此标准由UEFI联盟中的140多个技术公司共同创建,如intel、IBM、Microsoft、AMI等等。UEFI旨在提高软件互操作性和解决BIOS的局限性。它用来定义操作系统和系统固件之间的软件界面,作为BIOS的替代方案,其主要目的是为了提供一组在 OS 加载之前(启动前)在所有平台上一致的、正确指定的启动服务,被看做是有近20多年历史的 BIOS 的继任者,并且UEFI的security有所加强,在手机这个微型PC,或者说在android系统启动之中替代了bootloader和litter kernel,是新时代系统启动引导程序。
总的来说,UEFI是一个规范,被定义为一个软件接口,用于连接OS和遵守这个规范的平台固件platform firmware。
优化项 | UEFI | BIOS | 描述 |
开发效率 | • 开源
• 标准接口
• 绝大部分是c代码 | • 闭源
• 接口混乱
• 主要采用汇编 | 正是由于BIOS的闭源以及混乱的接口导致其停滞不前,并最终无法适用于新架构的芯片。UEFI的开源且指定了标准的接口规范,并且也同提供接口,将大部分代码替换成c进行编写,不再使用晦涩的汇编进行开发,这样大大降低了开发的难度,这也是其迅速发展的根本原因。 |
性能 | 异步+时钟中断 | 中断机制 | UEFI舍弃了硬件外部中断的低效方式,只保留了时钟中断机制,然后通过异步+事件来实现对外部设备的操作,性能由此得到了极大的提升。 |
扩展和兼容性 | 模块化驱动设计 | 静态链接 | UEFI采用了规范的模块化设计,在扩展功能的时候只需要动态链接其模块就可以实现,这样的扩展十分方便便捷。而传统的BIOS必须运行在16位的指令模式之下,寻址范围也十分有限,而UEFI支持64位程序,并兼容32位,这也是为什么老古董windows XP出现这么久了,稍微改改就可以安装在新的设备上。 |
安全性 | 安全 | 未考虑安全性问题 | UEFI安装的驱动设备是需要经过签名验证才可以安装的,并且还采用了一定的加密机制进行验证,这样的安全机制一定程度上可以保障我们设备的安全。 |
驱动器容量 | 支持容量>2TB的驱动器 | 不支持容量>2TB的驱动器 | • 传统的BIOS只支持容量不超过2TB的驱动器,因为常见的512Byte扇区的分区表的单个分区的第13-16字节是用来进行LAB寻址的,也就是以扇区为单位进行寻址。总共4个字节,也就是4*8 = 32位,也就是2^32个单位空间,以扇区为单位进行寻址,也就是每次512Byte,那么: 2^32*512 = 2^41B = 2^31KB = 2^21MB = 2^11GB = 2TB. 所以传统的BIOS支持的最大容量的驱动器不超过2TB,以硬件厂商1000:1024的计算方式,实际容 量是小于2TB的。
• UEFI支持64位的地址空间,所以其寻址偏移刚好为一个机器长度——64位,即8Byte,还是按照LAB寻址方式进行计算:2^64*512 = 2^73B = 2^13EB = 8ZB但是,微软官方给的资料显示是18EB(按照硬件厂商1000:1024计算)(10^60)/(10^60) = 18EB |
文件系统 | 拥有文件系统的支持 | 无 | 由于UEFI本身已经相当于一个微型的OS了,具备了文件系统的支持,能够直接读取FAT分区中的文件。 |
应用程序 | 可以开发出直接在UEFI下运行的应用程序 | 无 | 这类程序文件通常以efi结尾。既然,UEFI既可以直接识别FAT分区中的文件,又可以直接在其中运行应用程序,那么完全可以将win安装程序做成efi类型的应用程序,然后放在任意的FAT分区中,直接运行即可。这样一来,原来安装win操作系统这个过去看起来有些许小复杂的事情忽然变得异常简单,就像在win中打开一个qq一样简单。而这在BIOS上是无法做到,因为BIOS下启动OS之前,必须从硬盘上指定扇区读取系统的启动代码(包含在主引导记录中),然后从活动分区中引导OS的启动。对扇区的操作远远比不上对分区中的文件的操作来得直观和简单,所以在BIOS上安装win这类的OS,不得不使用一些工具对设备进行配置以达到启动要求。 |
二、Android中的bootloader
由于本人的主业还是从事android底层开发的工作,所以本系列文章都还是将主体放在android上,故不会讲PC端UEFI的一些设计。
UEFI的出道是在PC领域,UEFI+gpt以其自身优点干翻了传统bios+mbr,UEFI也成为了未来bootloader的发展方向,计算机软件界有一个名言,计算机科学领域的任何问题都可以通过增加一个间接的中间层来解决(抽象),UEFI也不例外,之所以bios不行一个重要的点就是因为他的兼容性,UEFI为固件和操作系统提供了统一的接口,打通了PC固件之间的鸿沟;安卓bootloader从最初使用uboot,到lk(目前大多数依然是lk),一直到现在选择使用uefi,也足以证明UEFI的优势;
原来的安卓启动是采用bootloader这种引导启动方式。在有的文章中,会将bootloader进行比较,有的又会说现在的安卓bootloader是使用UEFI,而且在查找有关Android启动流程或者说开机流程的文章里,大部分还是在loader层以bootloader作为启动流程中的一部分。这里,算是给自己统一下说法,早期的bootloader是一种引导程序的名称,后来采用了LK、UEFI之后,bootloader就是代指某种的引导程序的统称,换句话说,UEFI、LK都是安卓bootloader采用的一种引导方式。所以,在学习安卓开机流程的时候,如果不关注loader层,完全可以忽略这里的bootloader采用的是哪种方式。这里说的有点绕,简单来说bootloader可以理解为一种过时的引导程序(古早且已经被时代淘汰了),也可以理解为引导程序的统称(比如,UEFI是一种bootloader、LK是一种bootloader,甚至可以说BIOS是一种bootloader),现在我们讲bootloader就是在第二种理解。