自己动手写DSDT系列教程1-ASL(ACPI Source Language)基础篇

2024-04-16 21:08

本文主要是介绍自己动手写DSDT系列教程1-ASL(ACPI Source Language)基础篇,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

写在前面的话,鄙人不是一个主板BIOS开发工作者,以下对ASL的理解仅仅来源于http://www.acpi.info/上的ACPI Specification文档。因此难免会出现不少错误的理解,以及错误的观点,希望大家谅解以及纠正。
    首先,不得不说一下DSDT(Differentiated System Description Table)。什么是DSDT呢?其实它属于ACPI其中的一个表格,而ACPI是Advanced Configuration & Power Interface的缩写,高级配置和电源接口,从文字上就可以理解ACPI是一系列的接口,这个接口包含了很多表格,所以DSDT即是其中的一张表格同时也是一些接口。所以不难想象ACPI主要的功能就是提供操作系统一些服务以及提供一些讯息给操作系统使用。DSDT自然也不例外。ACPI的一个特色就是专有一门语言来编写ACPI的那些表格。它就是ASL(ACPI Source Language)也就是这盘文章的主角,ASL经过编译器编译后,就变成了AML(ACPI Machine Language),然后由操作系统来执行。既然ASL是一门语言,那就有它的准则。

ASL准则:
1、变量命名不超过4个字符,且不能以数字开头。联想一下看到过的DSDT代码看看,绝对不会超过。
2、Scope形成作用域,概念类似于数学中的集合{}。有且仅有一个根作用域,所以DSDT都以


DefinitionBlock ("xxxx", "DSDT", 0x02, "xxxx", "xxxx", xxxx)
{


开始,同时以


}


结束。这个就是根作用域。xxxx参数依次表示输出文件名、OEMID、表ID、OEM版本。第三个参数根据第二个参数指定,如上面所示。如果是"DSDT"就一定是0x02,其他参数都可以自由修改。
3、以“_”字符开头的函数和变量都是系统保留的,这就是为什么反编译某些AML以后得到的ASL出现_T_X,重新编译的时候会出现警告。
4、Method定义函数,函数可以定义在Device下或者Scope下,但是不能脱离Scope定义单独的函数,所以不会有这种情况出现。


Method (xxxx, 0, NotSerialized)
{
......
}
DefinitionBlock ("xxxx", "DSDT", 0x02, "xxxx", "xxxx", xxxx)
{
......
}


5、根作用域下有\_GPE,\_PR,\_SB,\_SI,\_TZ五个作用域。\_GPE就是ACPI的事件处理,\_PR处理器,\_SB所有的设备和总线。\_SI系统指示灯。_TZ热区,用于读取某些温度。不同属性的东西放在对应的作用域下。例如:
设备Device (PCI0)放在Scope (\_SB)里面


Scope (\_SB)
{
    Device (PCI0)
    {
        ....
    }
    ....
}


CPU相关的信息放在Scope (_PR)


Scope (_PR)
{
    Processor (CPU0, 0x00, 0x00000410, 0x06)
    {
        ....
    }
    ....
}


Scope (_GPE)放着相关的事件处理


Scope (_GPE)
{
    Method (_L0D, 0, NotSerialized)
    {
        ....
    }
    ....
}


乍一看不是函数吗?当然函数也可以放在这里。但是请注意函数名“_”开头,是系统保留的函数。
6、Device(xxxx)也可看做是一个作用域
7、符号“\”引用根作用域,“^”引用上级作用域
8、ASL中没有运算符,+-*/=是不会出现了,但是有等价的函数。
9、函数最多可以传递8个参数,在函数里用Arg0~Arg7表示,不可以自定义。
10、函数最多可以用8个局部变量,用Local0~Local7,不用定义,但是需要初始化才能使用,也就是一定要有一次赋值操作。

ASL常用的数据类型:
Integer(整数)、String(字符串)、Event(事件)、Buffer(数组)、Package(对象集合)
ASL定义变量:
例如:
Name(TEST,0)//定义一个整数
Name(MSTR,"ASL")//定义一个字符串


Name (_PRW, Package (0x02)
                {
                    0x0D,
                    0x03
                })


//定义一个Package
可以发现定义变量的时候不需要显式声明其类型
ASL赋值方法:
有且仅有一个,Store(a,b)如
Store(0,Local0)//Local0=0
Store(Local0,Local1)//Local0=Local1

ASL运算函数:
上面提到ASL没有运算符号,但是有运算函数
Add 整数相加
And 整数于
Decrement 整数自减1
Divide 整数除法
Increment 整数自增1
Mod 整数求余
Multiply 整数相乘
ShiftLeft 左移
ShiftRight 右移
Subtract 整数减法
Or 或
Not 取反
Nor 异或
等等,具体请查阅ACPI Specification
举例如下:


Add(1, 2, Local0) //Local0 = 1 + 2
And(0x11, 0x22, Local0) //Local0 = 0x11 & 0x22
Divide(10, 9, Local1, Local0) //Local0 = 10 / 9, Local1 = 10 % 9
Mod (10, 9, Local0) //Local0 = 10 % 9
Multiply(1, 2, Local0) //Local0 = 1 * 2
ShiftLeft(1, 20, Local0) // Local0 = 1 << 20
ShiftRight(0x10000, 4, Local0) // Local0 = 0x10000 >> 4
Subtract(2, 1, Local0) //Local0 = 2 - 1
Or(0x01, 0x02, Local0) //Local0 = 0x01 | 0x02
Not(0x00,Local0) //Local0 = ~(0x00)
Nor(0x11, 0x22, Local0) //Local0 = ~(0x11) & ~(0x22)


ASL逻辑运算:
LAnd 逻辑与
LEqual 逻辑相等
LGreater 逻辑大于
LGreaterEqual 逻辑大于等于
LLess 逻辑小于
LLessEqual 逻辑小于等于
LNot 逻辑反
LNotEqual 逻辑不等于
LOr 逻辑或


Store (LAnd(1, 1), Local0) //Local0 = 1 & 1
Store (LEqual(1, 1), Local0) //Local0 = (1 == 1)
Store (LGreater(1, 2), Local0) //Local0 = (1 > 2)
Store (LGreaterEqual(1, 2), Local0) //Local0 = (1 >= 2)
Store (LLess(1, 2), Local0) //Local0 = (1 < 2)
Store (LLessEqual(1, 2), Local0) //Local0 = (1 <= 2)
Store (LNot(0), Local0) //Local0 = !0
Store (LNotEqual(0, 1), Local0) //Local0 = (0 != 1)
Store (LOR(0, 1), Local0) //Local0 = (0 | 1)


不难发现逻辑运算只会有两种结果0或者1。

ASL函数的定义:
1、定义函数


Method(TEST)
{}


2、定义有两个输入参数的函数,以及使用局部变量Local0~Local7


Method(MADD,2)
{
    Store(Arg0, Local0)
    Store(Arg1, Local1)
    Add(Local0, Local1, Local0)
}


实现了两个参数的加法运算,因此传入的参数一定要隐式整形数。
3、定义带返回值的函数


Method(MADD,2)
{
    Store(Arg0, Local0)
    Store(Arg1, Local1)
    Add(Local0, Local1, Local0)
    Return (Local0)
}


例子为自定义加法的实现。函数实现如同系统函数Add一样的相加
Store(MADD(1,2), Local0) //Local0 = 1 + 2
4、定义可序列化的函数


Method(MADD, 2, Serialized)
{
Store(Arg0, Local0)
Store(Arg1, Local1)
Add(Local0, Local1, Local0)
Return (Local0)
}


这个有点类似于多线程同步的概念,也就是说,当函数声明为Serialized,内存中仅能存在一个实例。一般应用在函数中创建一个对象。应用举例说明:


Method(TEST, Serialized)
{
    Name(MSTR,"I will sucess"
}


如果这样子声明TEST这个函数,那么在两个地方同时调用这个函数


Device (Dev1)
{
     TEST()
}
Device (Dev2)
{
     TEST()
}


如果先执行Dev1的TEST,Dev2中的TEST将等待Dev1中的TEST函数执行完毕再执行。如果声明为


Method(TEST, NotSerialized)
{
Name(MSTR,"I will sucess"
}


那么将在其中一个Devx调用TEST的时候,另外一个调用失败,当它试图创建相同的字符串MSTR的时候。

ASL流程控制:
和常见的高级语言一样,ASL也有与之对应的控制流程语句。
Break
BreakPoint
Case
Continue
Default
Else
ElseIf
If
Return
Stall
Switch
While
(一)分支控制If, ElseIf, Else, Switch, Case
1、If用法介绍
例如下面的语句判断一下当前系统的接口是不是Darwin,如果是把OSYS = 0x2710


If (_OSI ("Darwin"))
{
    Store (0x2710, OSYS)
}


2、ElseIf、Else用法介绍,如果系统结构不是Darwin,另外如果系统不是Linux,那么OSYS = 0x07D0


If (_OSI ("Darwin"))
{
    Store (0x2710, OSYS)
}
ElseIf (_OSI ("Linux"))
{
    Store (0x03E8, OSYS)
}
Else
{
    Store(0x07D0, OSYS)
}


3、Switch, Case, Defaule, BreakPoint示例


Switch(Arg2)
{
    Case(1)
    {
If(LEqual(1, Arg1)
{
    Return (1)
}
BreakPoint
    }
    Case(2)
    {
        ....
        Return (2)
    }
    Default
    {
        BreakPoint
    }
}


Switch可以看做是一系列If....Else的集合。BreakPoint相当于断点,意味着退出当前Swtich
(二)循环控制While,Break,Continue以及暂停Stall示例


Store(10, Local0)
While (LAnd (0x00, Local0))
{
    Decrement (Local0)
    Stall (32)
}


Local0等于10,如果Local0逻辑于0不为真,Local0自减1,暂停32us,所以这段代码延时10 * 32 = 320 us。

累了,今天就写到这里,有了这些基础,鄙人觉得现在大部分论坛坛友对着DSDT的时候就不会是发呆又发呆,至少可以明白些少语句了。


原文出自:http://bbs.pcbeta.com/viewthread-944566-1-1.html


这篇关于自己动手写DSDT系列教程1-ASL(ACPI Source Language)基础篇的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/909895

相关文章

2025版mysql8.0.41 winx64 手动安装详细教程

《2025版mysql8.0.41winx64手动安装详细教程》本文指导Windows系统下MySQL安装配置,包含解压、设置环境变量、my.ini配置、初始化密码获取、服务安装与手动启动等步骤,... 目录一、下载安装包二、配置环境变量三、安装配置四、启动 mysql 服务,修改密码一、下载安装包安装地

电脑提示d3dx11_43.dll缺失怎么办? DLL文件丢失的多种修复教程

《电脑提示d3dx11_43.dll缺失怎么办?DLL文件丢失的多种修复教程》在使用电脑玩游戏或运行某些图形处理软件时,有时会遇到系统提示“d3dx11_43.dll缺失”的错误,下面我们就来分享超... 在计算机使用过程中,我们可能会遇到一些错误提示,其中之一就是缺失某个dll文件。其中,d3dx11_4

Linux下在线安装启动VNC教程

《Linux下在线安装启动VNC教程》本文指导在CentOS7上在线安装VNC,包含安装、配置密码、启动/停止、清理重启步骤及注意事项,强调需安装VNC桌面以避免黑屏,并解决端口冲突和目录权限问题... 目录描述安装VNC安装 VNC 桌面可能遇到的问题总结描js述linux中的VNC就类似于Window

Go语言编译环境设置教程

《Go语言编译环境设置教程》Go语言支持高并发(goroutine)、自动垃圾回收,编译为跨平台二进制文件,云原生兼容且社区活跃,开发便捷,内置测试与vet工具辅助检测错误,依赖模块化管理,提升开发效... 目录Go语言优势下载 Go  配置编译环境配置 GOPROXYIDE 设置(VS Code)一些基本

Windows环境下解决Matplotlib中文字体显示问题的详细教程

《Windows环境下解决Matplotlib中文字体显示问题的详细教程》本文详细介绍了在Windows下解决Matplotlib中文显示问题的方法,包括安装字体、更新缓存、配置文件设置及编码調整,并... 目录引言问题分析解决方案详解1. 检查系统已安装字体2. 手动添加中文字体(以SimHei为例)步骤

Java JDK1.8 安装和环境配置教程详解

《JavaJDK1.8安装和环境配置教程详解》文章简要介绍了JDK1.8的安装流程,包括官网下载对应系统版本、安装时选择非系统盘路径、配置JAVA_HOME、CLASSPATH和Path环境变量,... 目录1.下载JDK2.安装JDK3.配置环境变量4.检验JDK官网下载地址:Java Downloads

使用Docker构建Python Flask程序的详细教程

《使用Docker构建PythonFlask程序的详细教程》在当今的软件开发领域,容器化技术正变得越来越流行,而Docker无疑是其中的佼佼者,本文我们就来聊聊如何使用Docker构建一个简单的Py... 目录引言一、准备工作二、创建 Flask 应用程序三、创建 dockerfile四、构建 Docker

深度解析Spring AOP @Aspect 原理、实战与最佳实践教程

《深度解析SpringAOP@Aspect原理、实战与最佳实践教程》文章系统讲解了SpringAOP核心概念、实现方式及原理,涵盖横切关注点分离、代理机制(JDK/CGLIB)、切入点类型、性能... 目录1. @ASPect 核心概念1.1 AOP 编程范式1.2 @Aspect 关键特性2. 完整代码实

Java Web实现类似Excel表格锁定功能实战教程

《JavaWeb实现类似Excel表格锁定功能实战教程》本文将详细介绍通过创建特定div元素并利用CSS布局和JavaScript事件监听来实现类似Excel的锁定行和列效果的方法,感兴趣的朋友跟随... 目录1. 模拟Excel表格锁定功能2. 创建3个div元素实现表格锁定2.1 div元素布局设计2.

SpringBoot连接Redis集群教程

《SpringBoot连接Redis集群教程》:本文主要介绍SpringBoot连接Redis集群教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 依赖2. 修改配置文件3. 创建RedisClusterConfig4. 测试总结1. 依赖 <de