为什么ARM服务器使用ACPI而不是device tree
overview
ACPI可以用于ARMv8通用服务器,设计遵循ARM的SBSA (Server Base System Architecture) [0]和SBBR (Server Base Boot Requirements) [1]规格。
ACPI规范由UEFI论坛管理,可从http://www.uefi.org/specifications获取相关文档,该规范可通过http://www.uefi.org/acpi找到。
Why ACPI on ARM?
在研究ACPI和Linux之间接口的细节之前,理解ACPI的使用原因是很有用的。毕竟,Linux中已经有几种技术可以用来描述不可枚举的硬件。在本节中,我们总结了一篇来自Grant Likely的博客文章[2],它概述了ARMv8服务器使用ACPI背后的原因。
-
ACPI的字节码(AML)允许平台对
硬件行为进行编码
,而DT(device tree)明确地不支持这一点。对于硬件供应商来说,能够对行为进行编码是支持新硬件上的操作系统发布的关键工具。 -
ACPI的OSPM定义了一个电源管理模型,该模型将平台允许做的事情限制在特定的模型中,同时还提供了硬件设计的灵活性。
-
在企业服务器环境中,ACPI已经建立了当前在生产系统中使用的绑定(例如用于RAS)。DT还没有。这样的绑定可以在某些时候在DT中定义,但是这样做意味着ARM和x86将在固件和内核中使用完全不同的代码路径。
-
仅使用单个接口来描述平台和操作系统之间的抽象是很重要的。如果硬件供应商想要支持多个操作系统,就不需要同时实现DT和ACPI。而且,每个操作系统都使用统一的接口,这有利于更好的整体互操作性。
-
ACPI运作机制良好,Linux与硬件供应商和其他操作系统供应商处于同一位置。事实上,再也没有任何理由认为ACPI只属于Windows,或者Linux在这个领域是微软的第二选择。ACPI管理进入UEFI论坛已经显著地打开了规范开发过程,目前,对ACPI进行的很大一部分更改是由Linux驱动的。
ACPI让OS不用了解每个硬件的细节,OS不用针对每个设备做移植;ACPI让硬件厂商对电源管理行为负责,而不需要关心OS的发布节奏,且OS发布节奏也不受硬件的控制。
ACPI重要的另一个原因是现有的硬件和OS厂商已经使用ACPI搭建了通用的计算机系统协作机制,基础架构是现成的,绑定特性是现成的,处理过程也是现成的。DT虽然支持Linux直接集成硬件,但对服务器厂商需要的处理过程没有好的支持。当然,Linux可用去做这些支持,但这样的话,是对已有机制的重复创造。ACPI已经满足硬件厂商所需,微软不会使用DT,硬件厂商最后会提供两种不同的固件接口,一种给Linux,一种给Windows。
Kernel Compatibility
ACPI的主要工作是标准化,以使Linux内核后向兼容
。在服务器领域,软硬件都可能使用相当长的时间,ACPI在kernel和固件之间形成长期维护的一致性的抽象接口,不随软件和硬件变化而变化。由于抽闲层的存在,系统可以在不更换内核的情况下进行更新。
当Linux驱动或子系统第一次使用ACPI实现时,它需要一个特定版本的ACPI规范,即基线。虽然最早的内核版本第一次提供的基础版本的ACPI可能不是最优的,ACPI固件必须继续演进。当可能需要添加驱动(例如cpu电源管理)新加的功能不应该破坏旧的内核版本支持。更进一步的,ACPI固件在最新版本内核应该继续可以工作。
Booting using ACPI tables
在ARMv8上,将ACPI表传递给内核的唯一定义方法是通过UEFI系统配置表。这意味着ACPI只支持通过UEFI引导的平台。
当一个ARMv8系统启动时,它可以有DT信息,ACPI表,或者两者都有。如果没有使用命令行参数,内核将尝试使用DT进行设备枚举;如果没有DT,内核将尝试使用ACPI表。这两种情况都不可用,内核将无法引导。如果在命令行上使用acpi=force
,内核将首先尝试使用acpi表,但如果没有acpi表,则返回到DT。其基本思想是,除非绝对没有其他选择,否则内核不会引导失败。
ACPI表的处理可以通过在内核命令行上传递ACPI=off
来禁用;这是默认行为。
为了让内核加载和使用ACPI表,UEFI实现必须设置ACPI_20_TABLE_GUID指向RSDP表如果这个指针是不正确的,并且acpi=force被使用,内核将禁用acpi并尝试使用DT引导代替。如果指向RSDP表的指针是正确的,ACPIcore将使用UEFI提供的地址将该表映射到内核。
然后,ACPI核心将通过RSDP表中的地址来定位和映射所有其他ACPI表,以找到XSDT (eXtended System Description table)。XSDT依次向系统固件提供的所有其他ACPI表提供地址;然后ACPI核心将遍历这个表,并在列出的表中映射。
如果下面的表不完整,内核可能无法正确引导,因为它可能无法配置所有可用的设备。这个表的列表并不意味着包含所有的表;在某些环境中,可能需要其他表(例如,第18节中的任何一个APEI表)来支持特定的功能。
RSDP (Root System Description Pointer), section 5.2.5
XSDT (eXtended System Description Table), section 5.2.8
FADT (Fixed ACPI Description Table), section 5.2.9
DSDT (Differentiated System Description Table), section 5.2.11.1
MADT (Multiple APIC Description Table), section 5.2.12
GTDT (Generic Timer Description Table), section 5.2.24
If PCI is supported, the MCFG (Memory mapped ConFiGuration Table), section 5.2.6, specifically Table 5-31.
If booting without a console=<device> kernel parameter is supported, the SPCR (Serial Port Console Redirection table), section 5.2.6, specifically Table 5-31.
If necessary to describe the I/O topology, SMMUs and GIC ITSs, the IORT (Input Output Remapping Table, section 5.2.6, specifically Table 5-31).
If NUMA is supported, the SRAT (System Resource Affinity Table) and SLIT (System Locality distance Information Table), sections 5.2.16 and 5.2.17, respectively.
Programmable Power Control Resources
电源控制资源包括电压、电流和时钟。在ACPI中,不会使用到kernel的clock和regulator框架。
内核假设这些资源的电源控制是用电源资源对象表示的(ACPI第7.1节)。ACPI核心将根据需要正确地启用和禁用资源。为了让它工作,ACPI假设每个设备都定义了d状态,并且这些状态可以通过ACPI方法_PS0、_PS1、_PS2和_PS3
进行控制;在ACPI中,_PS0
是用来完全打开设备的调用方法,而_PS3
是用来完全关闭设备的。
Driver Recommendations
当为驱动程序添加ACPI支持时,不要移除任何DT处理。同一设备可以在许多不同的系统上使用。