AML
ACPI机器语言(AML)是ACPI使用的与平台无关的代码。 甚至需要关闭计算机的知识。 它可以在DSDT和SSDT表中找到,这两个表依次通过解析RSDT或XSDT来找到。
AML代码是在读取每个表时从该表的开头开始解析的字节代码。 它包含ACPI命名空间内的设备和对象的定义。 通过解析代码,注意所有适当的控制流语句,AML解释器可以建立系统内所有设备及其支持的属性和功能的数据库(参考配置和电源管理)。
该规范可从UEFI网站获得。 此外,英特尔在其 ACPICA 软件中提供了参考实现。
ASL和AML
ASL是ACPI源语言(source language)。 它是AML的字节码的一种更人性化的形式。 这种差异与汇编代码和实际二进制机器代码之间的差异相似。 英特尔ASL汇编器(IASL)可在许多Linux发行版上免费获得,并且可以在这些格式之间进行任意方向的转换。
示例ASL代码
下面是DSDT的ASL代码的一个非常简单的示例。
test.asl:
DefinitionBlock ("test.aml", "DSDT", 1, "OEMID ", "TABLEID ", 0x00000000)
{
Scope (_SB)
{
Device (PCI0)
{
Name (_HID, EisaId ("PNP0A03"))
}
}
}
然后可以通过运行‘iasl test.asl’生成test.aml将其编译为AML。
这是HP pavilion g6 (RTC) 的实际设备。 这被嵌入到一个更大的定义块中:
Device (RTC)
{
Name (_HID, EisaId ("PNP0B00")) // _HID: Hardware ID
Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
{
IO (Decode16,
0x0070, // Range Minimum
0x0070, // Range Maximum
0x01, // Alignment
0x08, // Length
)
IRQNoFlags ()
{8}
})
OperationRegion (CMS0, SystemCMOS, Zero, 0x40)
Field (CMS0, ByteAcc, NoLock, Preserve)
{
RTSE, 8,
Offset (0x02),
RTMN, 8,
Offset (0x04),
RTHR, 8,
Offset (0x06),
RTDY, 8,
RTDE, 8
}
}
请注意,该区域位于CMOS中。
从RTC开始,这是同一台PC上的PS/2键盘:
Device (PS2K)
{
Name (_HID, EisaId ("PNP0303")) // _HID: Hardware ID
Method (_STA, 0, NotSerialized) // _STA: Status
{
Return (0x0F)
}
Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
{
IO (Decode16,
0x0060, // Range Minimum
0x0060, // Range Maximum
0x01, // Alignment
0x01, // Length
)
IO (Decode16,
0x0064, // Range Minimum
0x0064, // Range Maximum
0x01, // Alignment
0x01, // Length
)
IRQ (Edge, ActiveHigh, Exclusive, )
{1}
})
Name (_PRS, ResourceTemplate () // _PRS: Possible Resource Settings
{
StartDependentFn (0x00, 0x00)
{
FixedIO (
0x0060, // Address
0x01, // Length
)
FixedIO (
0x0064, // Address
0x01, // Length
)
IRQNoFlags ()
{1}
}
EndDependentFn ()
})
Name (_PRW, Package (0x02) // _PRW: Power Resources for Wake
{
0x18,
0x03
})
Method (_PSW, 1, NotSerialized) // _PSW: Power State Wake
{
Store (Arg0, KBWK)
}
}
上述两个样本是通过我编写的实用程序收集的,该实用程序从注册表中获取DSDT数据,并由iASL进行反汇编。--Bellezzasolo 14:58, 20 January 2013 (CST)
这将定义一个表(DSDT),并请求将输出AML放在名为test.aml的文件中。 “OEMID” 是一个6个字符的字符串,定义了制造系统固件的OEM的名称,“TABLEID” 是一个8个字符的字符串,定义了表的名称 - 它通常是特定于OEM的。 DefinitionBlock行中的最后一个条目是OEM修订ID。 它在根命名空间中定义了一个命名空间,称为 _SB。 请注意,所有设备/作用域/对象名称的长度均为4个字符,因此有时用“_SB”表示。 _SB是ACPI命名空间中的一个特殊名称,称为“系统总线(System Bus)”,它是找到所有设备和总线对象的主要作用域。 有关预定义名称的列表,请参见ACPI规范表5-67。
在_SB范围内,我们定义了一个名为PCI0的设备,其中有一个名为_HID的对象。 _HID同样是指设备的即插即用(Plug and Play)硬件ID的预定义名称,在本例中,内置宏EisaId用于从“PNP0A03”生成值0x030ad041,PNP0A03是PCI根总线的PnP ID。 可从 [1] 获得相当完整的PNP id列表。
AML操作码
此表来自ACPI规范,其中提供的主要是在调试AML解析器期间使用的表。 例如,如果你的解析器失败,并且下一个字节 (它无法解析) 是 “0x72”,那么你可以参考此表以查看它是 “添加” 操作。 不要让这张表让你误以为AML是由一个简单指令的线性流组成的,一次只能解码一条指令。 大多数AML由嵌套的递归定义的结构和列表组成。
Value (Hex) | Name |
---|---|
0x00 | ZeroOp |
0x01 | OneOp |
0x06 | AliasOp |
0x08 | NameOp |
0x0A | BytePrefix |
0x0B | WordPrefix |
0x0C | DWordPrefix |
0x0D | StringPrefix |
0x0E | QWordPrefix |
0x10 | ScopeOp |
0x11 | BufferOp |
0x12 | PackageOp |
0x13 | VarPackageOp |
0x14 | MethodOp |
0x2E (‘.’) | DualNamePrefix |
0x2F (‘/’) | MultiNamePrefix |
0x30-0x39 ('0'-'9') | DigitChar |
0x41-0x5A (‘A’-‘Z’) | NameChar |
0x5B (‘[’) | ExtOpPrefix |
0x5B 0x01 | MutexOp |
0x5B 0x02 | EventOp |
0x5B 0x12 | CondRefOfOp |
0x5B 0x13 | CreateFieldOp |
0x5B 0x1F | LoadTableOp |
0x5B 0x20 | LoadOp |
0x5B 0x21 | StallOp |
0x5B 0x22 | SleepOp |
0x5B 0x23 | AcquireOp |
0x5B 0x24 | SignalOp |
0x5B 0x25 | WaitOp |
0x5B 0x26 | ResetOp |
0x5B 0x27 | ReleaseOp |
0x5B 0x28 | FromBCDOp |
0x5B 0x29 | ToBCD |
0x5B 0x2A | UnloadOp |
0x5B 0x30 | RevisionOp |
0x5B 0x31 | DebugOp |
0x5B 0x32 | FatalOp |
0x5B 0x33 | TimerOp |
0x5B 0x80 | OpRegionOp |
0x5B 0x81 | FieldOp |
0x5B 0x82 | DeviceOpList |
0x5B 0x83 | ProcessorOp |
0x5B 0x84 | PowerResOp |
0x5B 0x85 | ThermalZoneOpList |
0x5B 0x86 | IndexFieldOp |
0x5B 0x87 | BankFieldOp |
0x5B 0x88 | DataRegionOp |
0x5C (‘\’) | RootChar |
0x5E (‘^’) | ParentPrefixChar |
0x5F(‘_’) | NameChar |
0x60 (‘`’) | Local0Op |
0x61 (‘a’) | Local1Op |
0x62 (‘b’) | Local2Op |
0x63 (‘c’) | Local3Op |
0x64 (‘d’) | Local4Op |
0x65 (‘e’) | Local5Op |
0x66 (‘f’) | Local6Op |
0x67 (‘g’) | Local7Op |
0x68 (‘h’) | Arg0Op |
0x69 (‘i’) | Arg1Op |
0x6A (‘j’) | Arg2Op |
0x6B (‘k’) | Arg3Op |
0x6C (‘l’) | Arg4Op |
0x6D (‘m’) | Arg5Op |
0x6E (‘n’) | Arg6Op |
0x70 | StoreOp |
0x71 | RefOfOp |
0x72 | AddOp |
0x73 | ConcatOp |
0x74 | SubtractOp |
0x75 | IncrementOp |
0x76 | DecrementOp |
0x77 | MultiplyOp |
0x78 | DivideOp |
0x79 | ShiftLeftOp |
0x7A | ShiftRightOp |
0x7B | AndOp |
0x7C | NandOp |
0x7D | OrOp |
0x7E | NorOp |
0x7F | XorOp |
0x80 | NotOp |
0x81 | FindSetLeftBitOp |
0x82 | FindSetRightBitOp |
0x83 | DerefOfOp |
0x84 | ConcatResOp |
0x85 | ModOp |
0x86 | NotifyOp |
0x87 | SizeOfOp |
0x88 | IndexOp |
0x89 | MatchOp |
0x8A | CreateDWordFieldOp |
0x8B | CreateWordFieldOp |
0x8C | CreateByteFieldOp |
0x8D | CreateBitFieldOp |
0x8E | TypeOp |
0x8F | CreateQWordFieldOp |
0x90 | LandOp |
0x91 | LorOp |
0x92 | LnotOp |
0x92 0x93 | LNotEqualOp |
0x92 0x94 | LLessEqualOp |
0x92 0x95 | LGreaterEqualOp |
0x93 | LEqualOp |
0x94 | LGreaterOp |
0x95 | LLessOp |
0x96 | ToBufferOp |
0x97 | ToDecimalStringOp |
0x98 | ToHexStringOp |
0x99 | ToIntegerOp |
0x9C | ToStringOp |
0x9D | CopyObjectOp |
0x9E | MidOp |
0x9F | ContinueOp |
0xA0 | IfOp |
0xA1 | ElseOp |
0xA2 | WhileOp |
0xA3 | NoopOp |
0xA4 | ReturnOp |
0xA5 | BreakOp |
0xCC | BreakPointOp |
0xFF | OnesOp |