AML

来自osdev
Zhang3讨论 | 贡献2022年3月19日 (六) 10:01的版本 (创建页面,内容为“{{stub}} ACPI机器语言(AML)是ACPI使用的与平台无关的代码。 甚至需要关闭计算机的知识。 它可以在DSDTSSDT表中找到,这两个表依次通过解析RSDTXSDT来找到。 AML代码是在读取每个表时从该表的开头开始解析的字节代码。 它包含ACPI命名空间内的设备和对象的定义。 通过解析代码,注意所有适当的控制流语句,AML解释器可以建立系统内所有…”)
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
跳到导航 跳到搜索

This article is a stub! 此页面或段落为 草稿。 你可以通过更精确的编辑贡献 来帮助本wiki。

ACPI机器语言(AML)是ACPI使用的与平台无关的代码。 甚至需要关闭计算机的知识。 它可以在DSDTSSDT表中找到,这两个表依次通过解析RSDTXSDT来找到。

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