概述
V6.5规范相对于上一个版本增加对CXL内存的支持,增加对龙芯LoongArch处理器架构的支持、增加对机密计算时间日志的支持、增加对USB-C USB4的支持。
本文从广泛性和一般性上概要介绍了高级配置与电源接口(ACPI)的基本概念,方便对大家对ACPI有一个基础认识。除文中提到的示例外,文章不涉及ACPI的具体细节,如有需要,你可以访问文章末尾ACPI规范的链接了解ACPI各版本详细内容。
ACPI的历史背景
20世纪90年代中期,Intel、Microsoft、Toshiba、HP和Phoenix联合开发了ACPI接口并确定了接口规范。在此之前,操作系统(Operating System)主要使用基本输入输出系统(BIOS Basic Input/Output System)接口进行电源管理和设备发现与配置。这种电源管理方法利用操作系统调用BIOS原生能力来进行电源管理。BIOS根据探测输入输出(I/O)发现新设备(Device Discovery)并尝试为新设备加载正确的驱动程序(大家常听到的即插即用功能)。由于平台本身是不可枚举的,因此,设备的位置也可能写死在BIOS中。这些解决方案存在三方面问题,首先,操作系统或其上的应用程序可能会受到BIOS中电源管理设置的不良影响,导致系统在运行中或其他不正确的时间进入睡眠状态。其次,不同硬件制造商和不同BIOS供应商的电源管理接口都是专有的,这要求开发人员学习如何为每个单独的系统配置电源管理。第三,各种设备的默认设置也可能相互冲突,导致设备崩溃、行为异常或无法识别。
ACPI正是为了解决以上这些主要问题以及其他一些问题应运而生。
ACPI 的发展历史如下:
- 1997 年,由英特尔、微软、东芝公司共同提出、制定了 ACPI 1.0 规范。
- 2000 年 8 月,康柏和凤凰科技加入,推出 ACPI 2.0 规范。
- 2004 年 9 月,惠普取代康柏,推出 ACPI 3.0 规范。
- 2009 年 6 月 16 日,推出 ACPI 4.0 规范。
- 2011 年 11 月 23 日,推出 ACPI 5.0 规范。
- 2013 年 10 月,ACPI 的推广者们一致同意将 ACPI 的属有归到 UEFI 论坛。从那以后新的 ACPI 规范将由 UEFI 论坛制定。
- 2015年4月,推出 ACPI 6.0 规范
- 2022年八月,推出 ACPI 6.5 规范
什么是ACPI?
首先,ACPI可以被理解为一种与架构无关的电源管理和配置框架,作为操作系统内的一个子系统。该框架建立了一个硬件寄存器集,用于定义电源状态(如睡眠、休眠、唤醒等)。这个硬件寄存器集可以兼容专用硬件和通用硬件。
标准ACPI框架和硬件寄存器集的主要目的是在不直接从操作系统调用固件(Firmware)的情况下实现电源管理和系统配置。ACPI充当操作系统和系统固件之间的接口层,如下图示。
ACPI在系统中的位置
在这个接口层中,ACPI为操作系统提供了一种标准化的方式来与硬件交互,从而进行电源管理和设备配置,而无需深入了解每个硬件设备的具体细节。这样,开发者就可以编写与硬件无关的代码,提高系统的可移植性和可维护性。同时,ACPI也解决了之前提到的BIOS电源管理和设备发现与配置中的问题,如应用程序行为受BIOS设置影响、电源管理接口专有以及设备设置冲突等。
ACPI定义了两种在系统固件和操作系统之间通过ACPI子系统共享的数据结构:数据表和定义块(见下图)。这些数据结构是固件和操作系统之间的主要通信机制。数据表存储原始数据,由设备驱动程序使用。定义块由解释器可执行的字节码组成。
ACPI架构图
在初始化时,AML(ACPI机器语言)解释器将定义块中的字节码提取为可枚举对象。这些可枚举对象的集合构成了操作系统中的一个构造,称为ACPI命名空间(ACPI Namespace)。ACPI命名空间中的对象可以有一个预定义值,也可以由AML解释器计算得出。AML解释器在操作系统的指导下评估对象,然后与系统硬件交互以执行必要的操作。
定义块的字节码是从ACPI源语言(ASL)代码编译而来的。ASL是用于定义ACPI对象和编写控制方法的语言。ASL编译器将ASL翻译成ACPI机器语言(AML)字节码。AML是AML解释器处理的语言,如下图。
ASL编译成AML过程
通过这种方式,ASL为开发者提供了一种定义ACPI对象和控制方法的高级语言,而AML解释器则负责将这些定义转换为可由系统硬件执行的低级指令。
ACPI源语言(ASL)代码用于定义对象和控制方法。然后,ASL编译器将这些ASL代码转换为包含在ACPI定义块中的ACPI机器语言(AML)字节码。定义块由一个可识别的表头和可由AML解释器执行的字节码组成。
AML解释器(AML interpreter)执行字节码并评估定义块中的对象,以便字节码能够执行循环结构、条件跳转、访问定义的地址空间以及执行应用程序所需的其他操作。AML解释器对系统内存、I/O、PCI配置等已定义地址空间的读写权限。它将前述地址空间定义为多个对象,并通过这些对象的入口点来访问它们。这些对象可以直接赋值,或者必须由AML解释器进行评估和解析。
这些可枚举对象的集合是操作系统中的一个构造,称为ACPI命名空间。命名空间是系统中ACPI设备的层次结构表示。系统总线(System Bus)是这些ACPI设备枚举的根。在其他总线上可枚举的设备,如PCI或USB设备,通常不在命名空间中枚举。相反,它们自己的总线枚举设备并加载相应的驱动程序。然而,所有可枚举的总线都有一种编码技术,允许ACPI对设备的总线特定地址进行编码,以便在ACPI中找到它们,即使ACPI通常不会为这些设备加载驱动程序。这种设计使得ACPI能够跨不同的硬件平台和操作系统提供一致的电源管理和设备发现机制。
一般来说,具有_HID对象( hardware identification object 硬件标识对象)的设备会被ACPI枚举,并且它们的驱动程序会由ACPI加载。而具有_ADR对象(physical address object 物理地址对象)的设备通常不会被ACPI枚举,并且它们的驱动程序也不会由ACPI加载。通常,_ADR设备能够执行所有必要的功能而无需ACPI的介入,但在设备驱动程序无法执行某项功能或需要与系统固件通信的情况下,ACPI可以评估对象来执行所需的功能。
以PCI为例,PCI本身不支持热插拔(hotplug)。但是,PCI可以利用ACPI来评估对象并定义方法,从而允许ACPI填充在PCI上执行热插拔所需的功能,既,ACPI赋予了PCI设备热插拔功能。
ACPI的另一个方面是运行时模型,该模型处理系统运行期间发生的所有ACPI中断事件。ACPI会根据需要继续评估对象来处理这些事件。这个基于中断的运行时模型将在下面的“运行时模型”部分中更详细地讨论。在运行时,ACPI能够响应系统状态的变化,如电源状态的变化、设备的插入或移除等,从而确保系统能够正确地管理电源和设备资源。
ACPI初始化
了解ACPI如何工作的最佳方式是按照时间顺序来描述。启动系统时,固件会完成自身设置、初始化和自检。
然后,系统固件使用在固件初始化过程中获得的信息来更新ACPI表,根据需要添加各种平台配置和电源接口数据,之后才将控制权传递给引导加载程序。扩展根系统描述表(XSDT)是ACPI子系统使用的第一张表,它包含了系统上大多数其他ACPI表的地址。XSDT指向固定ACPI描述表(FADT)以及其他在初始化过程中由操作系统处理的主要表。操作系统初始化之后,FADT会指导ACPI子系统找到差分系统描述表(DSDT),该表也是命名空间的起点,因为它是包含定义块的第一个表。
然后,ACPI子系统处理DSDT,并开始从ACPI定义块构建命名空间。XSDT还指向次级系统描述表(SSDTs)并将它们添加到命名空间中。ACPI数据表为操作系统提供关于系统硬件的原始数据。
从ACPI表中构建命名空间后,操作系统开始遍历命名空间,并为在命名空间中遇到的所有_HID(硬件标识)设备加载设备驱动程序。过程见下图。
ACPI初始化过程
在上面的ACPI初始化图中,在将控制权移交给引导加载程序之前,系统固件会根据需要更新ACPI表,这些表包含仅在运行时可用的信息。XSDT是操作系统ACPI子系统使用的第一个表,它包含系统上大多数其他ACPI表的地址。XSDT指向FADT、SSDTs和其他主要的ACPI表。FADT指导ACPI子系统到DSDT,这是命名空间的开始,因为DSDT是包含定义块的第一个表。然后,ACPI子系统消耗DSDT并开始从定义块构建ACPI命名空间。XSDT还指向SSDTs并将它们添加到命名空间中。
运行时模型
系统启动并运行后,ACPI与操作系统协同工作,通过中断处理发生的所有ACPI事件。中断事件分为两种:固定事件和通用目的事件(GPE)。
固定事件是ACPI规范中具有预定义意义的事件。这些固定事件包括按下电源按钮或ACPI计时器溢出等操作。这些事件由操作系统处理程序直接处理。
GPEs是ACPI规范中没有预定义的事件。这些事件通常通过评估控制方法来处理,控制方法是命名空间中的对象,可以访问系统硬件。当ACPI子系统使用AML解释器评估控制方法时,GPE对象会根据操作系统的实现来处理事件。这可能涉及向设备发出通知,以调用设备驱动程序来执行特定功能。
我们将在下一节中讨论运行时模型的通用示例。
热事件示例
ACPI包含了一个热模型,系统可以通过主动方式(如打开风扇)或被动方式(如通过节流处理器来减少系统使用的电量)来控制系统温度。我们可以使用下图的一个通用热事件示例来演示ACPI运行时模型的工作原理。
通用热事件处理示例
ACPI热区包含控制方法,用于读取当前硬件系统温度和触发点。
在命名空间中首次发现热区时,操作系统会加载热区驱动程序,该驱动程序会评估热区以获取当前温度和触发点。
当硬件系统组件温度升高到足以触发触发点时,会发生热区GPE(通用目的事件)。
GPE会导致中断发生。当ACPI子系统收到中断时,它首先检查是否发生了任何固定事件。在此示例中,热区事件是GPE,因此没有发生固定事件。
然后,ACPI子系统在命名空间中搜索与中断的GPE编号相匹配的控制方法。找到后,ACPI子系统会评估该控制方法,该方法可能会访问硬件和/或通知热区处理程序。
然后,操作系统的热区处理程序将采取必要的操作来处理该事件,包括可能访问硬件。
ACPI是一个非常健壮的接口实现。热区触发点可以通知系统打开风扇、降低设备性能、读取温度、关闭系统或根据需求执行这些操作和其他操作的任意组合。
运行时模型作用于整个系统,以管理系统操作期间发生的所有ACPI事件。
总结
ACPI描述了概念和接口框架,并被实现为主机操作系统的一个子系统。ACPI表、处理程序、解释器、命名空间、事件和中断模型共同构成了ACPI的实现,在主机操作系统内部创建了ACPI子系统。从这个意义上说,ACPI是系统硬件/固件与操作系统及操作系统应用程序之间用于配置和电源管理的接口。这为各种操作系统提供了一种通过ACPI命名空间支持电源管理和配置的标准化方式。
ACPI命名空间是系统上所有ACPI设备的可枚举、层次化表示,用于查找和加载系统上ACPI设备的驱动程序。命名空间可以是动态的,通过实时评估对象和发送中断来实现,而无需操作系统调用本机系统固件代码。这使得设备制造商能够将自己的指令和事件编码到设备中。同时,通过实现标准化的电源管理接口,减少了不兼容性和不稳定性。
参考链接:
扩展阅读: