ACPI与UEFI

ACPI与UEFI

高级配置与电源接口(Advanced Configuration and Power Interface,ACPI)的应用已经广泛分布在计算机领略的各个细分市场。从手机、笔记本电脑、台式机到工作站和服务器上都可以找到它的身影。从体系架构上来看,不光X86阵营,ARM生态圈也加入进来。那究竟什么是ACPI,为什么要采用ACPI呢?

Why ACPI?

PC生态圈玩家众多,有OS 厂商(OSV)定期发布操作系统,如Windows,Ubuntu;芯片厂商提供CPU等,如Intel, AMD;主板厂商(OEM)提供电脑主板;扩展板提供显卡等等PCIE扩展卡;内存厂家推出一代一代不同的内存条等等。DIY玩家可以自由选择搭配合适/兼容的产品搭配出自己心仪的机器,休闲上网用户花2000多元就可以搭配出一套可用的电脑,而游戏玩家则可能花费上万元才能满足游戏配置需求。DIY市场的存在使一个厂商(例如苹果MacBook)垂直整合整个链条成为不可能。这样,OS厂家就面临一个难题:如何能够让一个OS可以在所有这些搭配中得到一致的运行感受?能不能抽象出一层接口,它既能用统一形式报告硬件的不同,又留给主板厂商足够的灵活性可以做出大胆的创新应用?

ACPI诞生

在ACPI诞生前,高级电源管理(APM, Advanced Power Management)将电源管理几乎完全交给BIOS,呆板而限制很多,这让微软十分不爽,它希望在电源管理和硬件配置上能有更多的自主权,这也是合理的,谁比操作系统更懂现在用户在干什么呢?

1997年由英特尔、微软、东芝公司共同提出、制定了ACPI 1.0规范。ACPI,顾名思义,就是配置硬件和管理电源的规范。2000年8月康柏和凤凰科技加入,推出 ACPI 2.0规格。2004年9月惠普取代康柏,推出 ACPI 3.0规格。2009年6月16日則推出 ACPI 4.0规格。2011年11月23日推出ACPI 5.0规格。由于ACPI技术正被多个操作系统和处理器架构采用,该规格的管理模式需要与时俱进。2013年10月,ACPI的推广者们一致同意将ACPI的属有归到UEFI论坛。从那以后新的ACPI规格将由UEFI论坛制定。最新的规范是ACPI 6.1,大家可以在Welcome to Unified Extensible Firmware Interface Forum上下载到最新的版本。

Windows 98是微软第一个支持ACPI的操作系统。FreeBSD v5.0是支持ACPI的第一个UNIX操作系统。Linux、NetBSD和OpenBSD等都支持ACPI。

ACPI整体框图如下:


可以看出它并不包含古老的PIC,CMOS,PIT等等规范,这些我们称之为Legacy支持。ACPI可以实现的功能包括:

1.系统电源管理(System power management)

2.设备电源管理(Device power management)

3. 处理器电源管理(Processor power management)

4.设备和处理器性能管理(Device and processor performance management)

5.配置/即插即用(Configuration/Plug and Play)

6.系统事件(System Event)

7.电池管理(Battery management)

8.温度管理(Thermal management)

9.嵌入式控制器(Embedded Controller)

10.SMBus控制器(SMBus Controller)

我们前面几篇CPU电源管理的定义也可以在这里找到出处,从整体来看整个电源状态转化图如下:


G0/G1/G2/G3表示整体的状态,S1/S2/S3/S4/S5表示睡眠状态,C1/C1../Cn和P0/P1..Px就是我们前文的Pstates(EIST)和CStates,D0/D1/D2/D3表示不同的设备电源状态。有机会我们再详细介绍G/S/D的内容。

从另外一个角度,我们可以将ACPI可以看作分为两个部分:

1. 各种表单(Tables)。这些表单描述了系统的各种状态,如MADT,SRAT等等,这些状态需要OS知晓,例如有多少个CPU(逻辑上),NUMA亲缘关系如何,APIC等等。

2. 由Differentiated System Description Table (DSDT)和Secondary System Description Table (SSDT)指向的AML代码。这是一种ACPI规范规定的伪代码,可以想象成Java的Bytecode(功能上相差巨大)。它由ASL编译而成(对应于Java source code)。ASL程序提供了OS和固件调用的接口(method)。ACPI定义了很多预定义的Method,通过它们,OS和firmware互相传送信息(例如 主板PCI设备树,IRQ,OS支持哪些功能等等);OS还可以调用firmware提供的接口;固件从OS那里能得到各种事件(Event)的通知等等。这点正是ACPI强大灵活之处。


ACPI VS APM

如前面提到的,ACPI取代了APM。这主要归咎于APM将电源管理归于BIOS,OS无从插手,而且其只有电源管理的能力而没有配置的功能(ACPI里的Configuration)。有趣的是APM也是微软和Intel发明的,那是在1992年,他们为了支持那时候才开始火热的IBM兼容机,才加上了电源管理模块。可是计划赶不上变化,才没过几年就不得不提出新的规范。从APM到ACPI的转化使得OS可以全面掌控各个电源模式的转化,并提供了配置功能。


ACPI VS FDT/DT

对于ARM和PowerPC世界的人来说,FDT(Flattened Device Tree)/DT(Device Tree)已经占据统治地位很久了。它的诞生源于Linus对于ARM各种SOC与Linux kernel driver强耦合性的一次大爆发(说是 pain in the ass)。从此DT的被设计出来了,ARM的耦合性得到了一定的缓解。那时ARM控制着嵌入式和手机世界,X86统治着PC和服务器,曲径分明,井水不犯河水,而ACPI和FDT也相安无事。和平没有持续很久,在X86试图进入手机领域时,ARM也试图进入PC和服务器,大战爆发了。ARM世界的FDT在新战场受到了残酷的抵抗,PC和服务器的玩家们不喜欢FDT,他们希望用一套工具集(toolchain)能同时解决两家问题,他们提出的理由也很有道理:FDT没有ACPI灵活!确实,FDT虽然在提供各种表单方面近似于ACPI,却缺少AML/ASL这样的灵活性。结局是ARM世界宣布在PC和服务器领域全面淘汰FDT,换用ACPI,而在嵌入式系统继续使用FDT。这也是合理的,毕竟嵌入式系统不需要这么多的灵活性,而迁移的代价是巨大的。另一方面,ACPI却随着X86进入嵌入式领域而在X86嵌入式领域生根发芽。

ACPI VS UEFI???

有人也许会说ACPI提供了OS可用的硬件抽象和接口(method),UEFI也提供了抽象和接口,是不是也有冲突?其实两者面向的方面不同,ACPI主要是从硬件抽象的角度来抽象硬件,UEFI是从软件一致方向定义规范。这也是他们不但没有替代关系,反而从ACPI 5.0 开始ACPI并入UEFI论坛管理的原因。需要指出的是ACPI和UEFI没有绑定关系,ACPI可以在uboot上实现,而UEFI也可以报告DT,但他们一起工作起来会更加顺畅。UEFI提供了帮助安装更新ACPI table的接口(protocol).大家可以在UEFI/PI spec里面找到相应的接口定义。

后记

ACPI规范林林总总一千多页,涵盖了很多方面,从EC到服务器的错误报告(APEI)很多细节,这里只是从整体介绍一下。

UEFI历史和架构其他文章:

UEFI和UEFI论坛 - 知乎专栏

UEFI背后的历史 - 知乎专栏

ACPI与UEFI - 知乎专栏

UEFI安全启动 - 知乎专栏

UEFI与硬件初始化 - 知乎专栏

UEFI架构 - 知乎专栏

欢迎大家关注本专栏和用微信扫描下方二维码加入微信公众号"UEFIBlog",在那里有最新的文章。同时欢迎大家给本专栏和公众号投稿!

用微信扫描二维码加入UEFIBlog公众号
编辑于 2017-10-28

文章被以下专栏收录

    从首次运用于Intel 安腾处理器,到第一版统一的可扩展固件接口(UEFI)规范出版,无论是在高性能服务器,移动设备或是深度嵌入式设备等,UEFI已在所有平台完全淘汰了BIOS。这里有关于UEFI的一切。