注意
Microsoft 支持多样化的包容性环境。 本文包含对 Microsoft 无偏见通信 风格指南识别为排除项的术语的参考。 本文中的单词或短语用于一致性,因为它当前显示在软件中。 当软件更新为删除语言时,本文将更新为对齐方式。
总结
- 创建使用 AcpiGenFx 生成 ACPI 表的 .NET 应用
适用于
Windows 10
Windows SoC 和平台启动
重要的 API
在对象浏览器中打开 AcpiGenFx
使用 Visual Studio 中的 IntelliSense 功能确定方法和属性
使用 ACPI 生成框架 (AcpiGenFx) 库编写生成 ACPI 表的应用。
在 Windows 10 中,新的 C# 库 AcpiGenFx 使你能够更轻松地编写一个应用,用于创建 ACPI 表,用于描述平台上的硬件设备和资源,例如中断控制器、SD 主机控制器、GPIO 和 I2C 设备。 通过使用框架对象公开的方法和属性,可以描述设备、资源和依赖项,而无需知道 ACPI 表的确切语法或引用 ACPI 规范。 AcpiGenFx 不仅生成独立于 OS 的 ACPI 计算机语言 (ASL) 代码,还了解特定于 Windows 的要求。
应用根据这些说明生成相关的 ACPI 表文件(*.aslc 和 *.asl)。 在生成时,AcpiGenFx 静态分析平台说明、检测周期性或未解决的依赖项、设备命名和 UUID 冲突、资源到控制器映射等错误。 因此,生成的 ASL 代码更易于调试,因为 AcpiGenFx 检查最常见的错误,并抽象出唯一的 ACPI 实现详细信息。
AcpiGenFx 本质上是声明性的:其输出仅是静态数据,它不设计用于生成动态运行时方法。 如果框架未涵盖用例(如高级 Off-SoC 外围设备电源管理),则必须在 Windows 平台扩展驱动程序中实现方法,或手动添加到 AcpiGenFx 生成的 ASL 代码中。
开始之前
在 WDK 安装的 AcpiGenFx 文件夹中找到以下文件。
WDK 的“工具”文件夹中提供了AcpiGenFx.dll和相关示例。 在“工具”目录中,导航到目标体系结构文件夹,然后导航到 AcpiGenFx 文件夹。 例如,x86 版本位于 C:\Program Files (x86)\Windows Kits\10\Tools\x86\ACPIGenFx 中。
AcpiGenFx.dll
需要使用 ACPIGenFx。
DSDTSamples
将此项目用作设计整个平台的 ACPI 固件的起点。 输出是一组完整的 ACPI 表,包括 DSDT、FADT 和 MADT。
SSDTSamples
将此项目用作起点,将外围设备添加到现有系统。 此示例演示如何描述传感器设备及其资源。 输出是 ASL 中的 ACPI SSDT 表。
下载 Windows 10 工具包、工具和代码示例。
创建平台
在 Visual Studio 中,打开新的 C# 控制台项目。
添加对AutoAcpi.dll程序集的引用。 在 “项目” 菜单下,单击“ 添加引用”。 单击“浏览”并导航到AutoAcpi.dll的位置。 单击“确定”。
在解决方案资源管理器中,展开“引用”并选择 acpigenfx。 在对象浏览器中查看对象(查看 > 对象浏览器)。
面向 .NET Framework 4.5 或更高版本。 打开项目属性。 在 “应用程序 ”页上,确保 目标框架 设置为 .NET Framework 4.5。
在
Using
应用程序的代码开头添加 AutoAcpi 对象的指令。创建平台对象。 基于体系结构,通过调用 Platform.CreateArmPlatform 或 Platform.Createx86Platform 实例化 Platform 对象。 指定 OEMID、OEMTableID、Creator、Revision 和 FileName。
调用 Platform.WriteAsl 以写入文件。
此示例演示如何实例化平台。
using AutoAcpi; namespace ACPI { class Program { static void Main(string[] args) { ArmPlatform myPlatform = Platforms.CreateArmPlatform( OEMID: "MSFT", OEMTableID: "EDK2", CreatorID: "MSFT", Revision: 1, FileName: "Platform"); myPlatform.WriteAsl(); } } }
单击“开始”生成并运行应用。 Visual Studio 在 “输出 ”窗口中显示生成进度。 (如果输出窗口不可见,请选择“视图”菜单中的“输出”。
打开 project\bin\Debug 或 Release\Output 下命名的文件夹。 输出文件夹包含应用生成的文件。 查看 SSDT.asl 的内容。
下面是前面的示例的输出。
DefinitionBlock ("Platform.aml", "DSDT", 5, "MSFT", "EDK2", 1) { Scope (\_SB_) { } }
该应用生成两个附加文件夹:Aslc 和 Bin。 Aslc 包含 aslc 格式的所有固件表。 Bin 包含二进制 Blob 格式的所有固件表。
使用 WDK 中提供的asl.exe编译器将 ASL 代码文件编译为 ACPI 计算机语言 (AML) 二进制文件。
在 DSDT 中添加设备和资源
可以将组件添加到平台。 通常,这些组件包括处理器、总线控制器、电源资源等。 下面是 DSDTSamples 中使用的一些组件。
对象类型 | 创建方法 | 组件 |
---|---|---|
ACAdapter | Platform.AddACAdapter | 添加 AC 适配器。 |
BatteryDevice | Platform.AddBatteryDevice BatteryDevice.ThermalLimit |
添加电池设备并指定其热限制。 |
ButtonArrayDevice | Platform.AddButtonArrayDevice ButtonArrayDevice.AddBackButton ButtonArrayDevice.Add相机ShutterButton ButtonArrayDevice.Add相机AutofocusButton ButtonArrayDevice.AddGenericButton ButtonArrayDevice.AddPowerButton ButtonArrayDevice.AddRotationLockButton ButtonArrayDevice.AddSearchButton ButtonArrayDevice.AddVolumeDownButton ButtonArrayDevice.AddVolumeUpButton ButtonArrayDevice.AddWindowsHomeButton |
添加按钮,如 Windows 主页、后退、音量 +/-、电源、旋转锁和搜索。 |
DisplaySensor | Platform.AddDisplaySensor | 添加显示传感器。 |
GenericDevice | Platform.AddGenericDevice | 添加可用于替换框架中任何类型的内部支持设备的通用设备。 |
GpioController | Platform.AddGpioController | 添加 GPIO 控制器和关联的资源,例如中断、I/O 和事件。 |
HidOverI2C | Platform.AddHidI2CDevice | 添加连接到 I2C 总线的 HID 设备。 |
I2CController | Platform.AddI2CController | 添加 I2C 控制器和关联的资源,例如中断、I/O 和事件。 |
KDNet2Usb | Platform.AddKDNet2Usb | 通过 USB 使用 Kdnet 添加对内核调试的支持。 |
PEPDevice | Platform.AddPepDevice | 添加 PEP 设备及其返回包和静态类型的资源和方法。 |
处理器 ProcessorAggregator |
Platform.AddProcessor Platform.AddProcessorAggregator |
添加处理器和处理器聚合器。 |
RTCDevice | Platform.AddRTCDevice | 添加 ACPI 时间和警报设备。 |
SdHostController | Platform.AddSdHostController | 添加 SD 主机控制器。 |
SerialPort | Platform.AddSerialPort | 添加对串行和 UART 设备的支持。 |
ThermalZone | Platform.AddThermalZone | 添加热区域和关联的采样和轮询周期。 |
XhciUsbController EhciUsbController UsbDevice |
Platform.AddEhciUsbController Platform.AddXhciUsbController EhciUsbController.AddUsbDevice XhciUsbController.AddUsbDevice UsbDevice.AddUsbDevice |
添加 USB 主机控制器和子设备(包括中心)。 |
若要查看完整列表,请在对象浏览器中打开 AcpiGenFx。 使用 IntelliSense 确定对象公开的方法(和参数)和属性。 有关演示如何添加类和设置上表中列出的属性的示例代码,请参阅 DSDTSamples 项目。
添加调试支持
若要将端口设置为可调试端口, 请将对象的 DebugEnabled 属性设置为“true”。
例如,你可能想要使用 USB 调试端口描述 xHCI 主机控制器。 在应用中,调用 Platform.AddXhciUsbController 以获取 XhciUsbController 对象,并将 DebugEnabled 属性设置为“true”。 AcpiGenFx 生成一个 Microsoft DBG2 表,该表自动包含在应用的 Output\Aslc 文件夹中。
下面是有关如何添加 xHCI 主机控制器并将其声明为可调试的示例。
XhciUsbController usb1 = Platform.AddXhciUsbController("USB1", "XHCICONT", 0);
usb1.Description = "USB Controller with Debug Support";
Memory32Fixed mem = usb1.AddMemory32Fixed(true, 0xf9000000, 0xfffff, "");
usb1.AddMemory32Fixed(true, 0xf7000000, 0xfffff, "");
usb1.AddInterrupt(InterruptType.Level, InterruptActiveLevel.ActiveHigh, SharingLevel.Shared, 0x8);
usb1.AddInterrupt(InterruptType.Level, InterruptActiveLevel.ActiveHigh, SharingLevel.Shared, 0x9);
usb1.DebugEnabled = true;
mem.DebugAccessSize = DebugAccessSize.DWordAccess;
在前面的代码片段中,xHCI 主机控制器具有中断资源和调试支持。 它依赖于 PEP 设备和 GPIO 控制器。 若要查看这些设备的说明,请参阅 DSDTSamples。
此示例演示如何将 I2C 控制器添加到 DSDT。
I2CController i2c = Platform.AddI2CController("I2C1", "I2CCONTR", 0);
i2c.AddMemory32Fixed(true, 0xf9999000, 0x400, "");
i2c.AddInterrupt(InterruptType.Level, InterruptActiveLevel.ActiveHigh, SharingLevel.Exclusive, 40);
下面是控制台应用的输出,其中包含 xHCI 主机和 I2C 控制器的上述定义。
DefinitionBlock ("Platform.aml", "DSDT", 5, "MSFT", "EDK2", 1)
{
Scope (\_SB_)
{
//
// Description: USB Controller with Debug Support
//
Device (USB1)
{
Name (_HID, "XHCICONT")
Name (_CID, "PNP0D10")
Name (_UID, 0x0)
Method (_STA)
{
Return(0xf)
}
Method (_CRS, 0x0, NotSerialized) {
Name (RBUF, ResourceTemplate () {
MEMORY32FIXED(ReadWrite, 0xF9000000, 0xFFFFF, )
MEMORY32FIXED(ReadWrite, 0xF7000000, 0xFFFFF, )
Interrupt(ResourceConsumer, Level, ActiveHigh, Shared) { 0x8 }
Interrupt(ResourceConsumer, Level, ActiveHigh, Shared) { 0x9 }
})
Return(RBUF)
}
}
//
// Description: This is an i2cController.
//
Device (I2C1)
{
Name (_HID, "I2CCONTR")
Name (_CID, "")
Name (_UID, 0x0)
Method (_STA)
{
Return(0xf)
}
Method (_CRS, 0x0, NotSerialized) {
Name (RBUF, ResourceTemplate () {
MEMORY32FIXED(ReadWrite, 0xF9999000, 0x400, )
Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 0x28 }
})
Return(RBUF)
}
}
}
}
生成项目后,在项目目录中导航到 Output\Aslc。 Dbg2.aslc 文件包含如下所示的 DB2 表:
// Debug Port Table (DBG2)
// Automatically generated by AutoAcpi
#include "AutoACPI.h"
char DBG2[112] = {
0x44, 0x42, 0x47, 0x32, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00,
0x4D, 0x53, 0x46, 0x54, 0x20, 0x20, 0x45, 0x44, 0x4B, 0x32,
0x20, 0x20, 0x20, 0x20, 0x01, 0x00, 0x00, 0x00, 0x4D, 0x53,
0x46, 0x54, 0x01, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x02, 0x0E, 0x00,
0x36, 0x00, 0x00, 0x00, 0x44, 0x00, 0x02, 0x80, 0x00, 0x00,
0x00, 0x00, 0x16, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x03,
0x00, 0x00, 0x00, 0xF9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0xF7, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0x0F, 0x00, 0xFF, 0xFF, 0x0F, 0x00, 0x22, 0x5C,
0x5C, 0x5F, 0x53, 0x42, 0x5F, 0x2E, 0x55, 0x53, 0x42, 0x31,
0x22, 0x00
};
void * ReferenceDBG2Table(void) {
return (void *) &DBG2;
}
在 SSDT 中添加外围设备的 ACPI 说明
通过调用 Platform.CreateArmPlatform 或 Platform.Createx86Platform 创建平台对象。
将 SSDT 属性设置为 true。 这向框架指示此表是 SSDT。
创建设备并分配资源。 例如,对于此处所示的传感器设备,示例调用 Platform.AddGenericDevice 并指定设备名称、硬件 ID 和唯一实例。 连接到 I2 C 串行总线的传感器设备 I2C1,DSDT中介绍。
namespace SSDTSample
{
class Program
{
static void Main(string[] args)
{
ArmPlatform Platform = Platforms.CreateArmPlatform(
OEMID: "MSFT",
OEMTableID: "EDK2",
CreatorID: "MSFT",
Revision: 1,
FileName: "SSDT"
);
platform.SSDT = true;
var sensor = platform.AddGenericDevice("ADXL", "ACPI\\ADXL345Acc", 1);
sensor.AddI2CSerialBus(
SlaveAddress: 0x1d,
Mode: SlaveMode.ControllerInitiated,
ConnectionSpeed: 400000,
addressmode: AddressMode._7Bit,
controllername: "I2C1"
);
platform.WriteAsl();
}
}
}
下面是前面的示例的输出。
DefinitionBlock ("SSDT.aml", "SSDT", 5, "MSFT", "EDK2", 1)
{
Scope (\_SB_)
{
Device (ADXL)
{
Name (_HID, "ACPI\ADXL345Acc")
Name (_UID, 0x1)
Method (_STA)
{
Return(0xf)
}
Method (_CRS, 0x0, NotSerialized) {
Name (RBUF, ResourceTemplate () {
I2CSerialBus(0x1D, ControllerInitiated, 0x61A80, AddressingMode7Bit, "I2C1", 0, ResourceConsumer, , RawDataBuffer() { 0 })
})
Return(RBUF)
}
}
}
}
在开发和测试过程中替换 ACPI 固件
在开发和测试方案中,可以替换从设备上的asl.exe编译器生成的 AML 二进制文件。 为此,请将 AML 二进制文件重命名为acpitabl.dat,并将其移动到 %windir%\system32。 在启动时,Windows 会将 ACPI 固件中存在的表替换为acpitabl.dat中的表。
确保使用以下命令启用测试签名:
bcdedit /set testsigning on