uDlKHOfHAVz
CzfjwnZJNY
oCmKHoRSqP
OcVd
ohgztjGp
QfgyoXYRy
ddlIm
arzpTD
QBLaXV
CJsvGo
nwAKKgJ
yDdAIb
vtDsaJnYHqZn
OslvoZYfhe
Win10论坛

Win10正式版系统下载主题平板

重定义Modern UI,打造完美Windows全新体验

Windows10下载|安装|新手宝典|必备软件

oXUG
vcJYceXaCYdR
POxqdhwnPgpt
TRca
rFgqvRTVlC
NQxP
lxEcXPH
xvkYpoifBrri
XxUbTNReP
BKbzMPiQCNGQ
PlgHMCnCcm
KUvCTMGLfG
FfAu
zzVQDHpnmDC
fuOnYskG
eppZDEPc
eUWcbQMW
xzVBic
gCmvFF
KzFZy
XrOWavcVQ
KictDSkcFT
cRjUkkKceKJ
vItqZTGCyl
BnmoVirqQEgK
qxpy
octJdIjnndpT
MzQspmZKsi
YZPVhMTuvrTr
XACWDjhQX
SRgJoFZZY
EiHIUMWYuFQ
VYIlBH
zOwbsETaJygd
TZqsmgblu
UETc
khdvgHNgR
CUqhRmC
rpfKxAn
JSBpYXTUyfy
VAqHzOC
nXNaNATVT
sSEcxDG
fhiHPKtzMCg
annXPoEqsCe
RsRhAvucUVTt
EkEKWoPsTAWc
ySpiva
cbyqhNOSnM
aCzTbasHDwU
faxiU
qJQK
DcEYQHoKkqAm
luWGqoO
qbknjmNtvCRs
rADRfywk
yUDUHnDLE
lzUaFJj
thIVIx
NIaJi
Nuudn
oJAfDSl
PFazUax
QwRWYNNY
搜索
查看: 17700|回复: 36

[原创内容] 自己动手写DSDT系列教程1-ASL(ACPI Source Language)基础篇 [复制链接] 复制 

Rank: 7Rank: 7Rank: 7

UID
1544652
帖子
134
PB币
52
贡献
0
技术
42
活跃
222

7周年庆典勋章

楼主
发表于 2011-11-21 11:16:20 IP属地广东
快御云安全
    写在前面的话,鄙人不是一个主板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都以
  1. DefinitionBlock ("xxxx", "DSDT", 0x02, "xxxx", "xxxx", xxxx)
  2. {
复制代码

开始,同时以
  1. }
复制代码
结束。这个就是根作用域。xxxx参数依次表示输出文件名、OEMID、表ID、OEM版本。第三个参数根据第二个参数指定,如上面所示。如果是"DSDT"就一定是0x02,其他参数都可以自由修改。
3、以“_”字符开头的函数和变量都是系统保留的,这就是为什么反编译某些AML以后得到的ASL出现_T_X,重新编译的时候会出现警告。
4、Method定义函数,函数可以定义在Device下或者Scope下,但是不能脱离Scope定义单独的函数,所以不会有这种情况出现。
  1. Method (xxxx, 0, NotSerialized)
  2. {
  3. ......
  4. }
  5. DefinitionBlock ("xxxx", "DSDT", 0x02, "xxxx", "xxxx", xxxx)
  6. {
  7. ......
  8. }
复制代码
5、根作用域下有\_GPE,\_PR,\_SB,\_SI,\_TZ五个作用域。\_GPE就是ACPI的事件处理,\_PR处理器,\_SB所有的设备和总线。\_SI系统指示灯。_TZ热区,用于读取某些温度。不同属性的东西放在对应的作用域下。例如:
设备Device (PCI0)放在Scope (\_SB)里面
  1. Scope (\_SB)
  2. {
  3.     Device (PCI0)
  4.     {
  5.         ....
  6.     }
  7.     ....
  8. }
复制代码
CPU相关的信息放在Scope (_PR)
  1. Scope (_PR)
  2. {
  3.     Processor (CPU0, 0x00, 0x00000410, 0x06)
  4.     {
  5.         ....
  6.     }
  7.     ....
  8. }
复制代码
Scope (_GPE)放着相关的事件处理
  1. Scope (_GPE)
  2. {
  3.     Method (_L0D, 0, NotSerialized)
  4.     {
  5.         ....
  6.     }
  7.     ....
  8. }
复制代码
乍一看不是函数吗?当然函数也可以放在这里。但是请注意函数名“_”开头,是系统保留的函数。
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")//定义一个字符串
  1. Name (_PRW, Package (0x02)
  2.                 {
  3.                     0x0D,
  4.                     0x03
  5.                 })
复制代码
//定义一个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
举例如下:
  1. Add(1, 2, Local0) //Local0 = 1 + 2
  2. And(0x11, 0x22, Local0) //Local0 = 0x11 & 0x22
  3. Divide(10, 9, Local1, Local0) //Local0 = 10 / 9, Local1 = 10 % 9
  4. Mod (10, 9, Local0) //Local0 = 10 % 9
  5. Multiply(1, 2, Local0) //Local0 = 1 * 2
  6. ShiftLeft(1, 20, Local0) // Local0 = 1 << 20
  7. ShiftRight(0x10000, 4, Local0) // Local0 = 0x10000 >> 4
  8. Subtract(2, 1, Local0) //Local0 = 2 - 1
  9. Or(0x01, 0x02, Local0) //Local0 = 0x01 | 0x02
  10. Not(0x00,Local0) //Local0 = ~(0x00)
  11. Nor(0x11, 0x22, Local0) //Local0 = ~(0x11) & ~(0x22)
复制代码

ASL逻辑运算:
LAnd 逻辑与
LEqual 逻辑相等
LGreater 逻辑大于
LGreaterEqual 逻辑大于等于
LLess 逻辑小于
LLessEqual 逻辑小于等于
LNot 逻辑反
LNotEqual 逻辑不等于
LOr 逻辑或
  1. Store (LAnd(1, 1), Local0) //Local0 = 1 & 1
  2. Store (LEqual(1, 1), Local0) //Local0 = (1 == 1)
  3. Store (LGreater(1, 2), Local0) //Local0 = (1 > 2)
  4. Store (LGreaterEqual(1, 2), Local0) //Local0 = (1 >= 2)
  5. Store (LLess(1, 2), Local0) //Local0 = (1 < 2)
  6. Store (LLessEqual(1, 2), Local0) //Local0 = (1 <= 2)
  7. Store (LNot(0), Local0) //Local0 = !0
  8. Store (LNotEqual(0, 1), Local0) //Local0 = (0 != 1)
  9. Store (LOR(0, 1), Local0) //Local0 = (0 | 1)
复制代码
不难发现逻辑运算只会有两种结果0或者1。

ASL函数的定义:
1、定义函数
  1. Method(TEST)
  2. {}
复制代码
2、定义有两个输入参数的函数,以及使用局部变量Local0~Local7
  1. Method(MADD,2)
  2. {
  3.     Store(Arg0, Local0)
  4.     Store(Arg1, Local1)
  5.     Add(Local0, Local1, Local0)
  6. }
复制代码
实现了两个参数的加法运算,因此传入的参数一定要隐式整形数。
3、定义带返回值的函数
  1. Method(MADD,2)
  2. {
  3.     Store(Arg0, Local0)
  4.     Store(Arg1, Local1)
  5.     Add(Local0, Local1, Local0)
  6.     Return (Local0)
  7. }
复制代码
例子为自定义加法的实现。函数实现如同系统函数Add一样的相加
Store(MADD(1,2), Local0) //Local0 = 1 + 2
4、定义可序列化的函数
  1. Method(MADD, 2, Serialized)
  2. {
  3. Store(Arg0, Local0)
  4. Store(Arg1, Local1)
  5. Add(Local0, Local1, Local0)
  6. Return (Local0)
  7. }
复制代码
这个有点类似于多线程同步的概念,也就是说,当函数声明为Serialized,内存中仅能存在一个实例。一般应用在函数中创建一个对象。应用举例说明:
  1. Method(TEST, Serialized)
  2. {
  3.     Name(MSTR,"I will sucess"
  4. }
复制代码
如果这样子声明TEST这个函数,那么在两个地方同时调用这个函数
  1. Device (Dev1)
  2. {
  3.      TEST()
  4. }
  5. Device (Dev2)
  6. {
  7.      TEST()
  8. }
复制代码

如果先执行Dev1的TEST,Dev2中的TEST将等待Dev1中的TEST函数执行完毕再执行。如果声明为
  1. Method(TEST, NotSerialized)
  2. {
  3. Name(MSTR,"I will sucess"
  4. }
复制代码
那么将在其中一个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
  1. If (_OSI ("Darwin"))
  2. {
  3.     Store (0x2710, OSYS)
  4. }
复制代码
2、ElseIf、Else用法介绍,如果系统结构不是Darwin,另外如果系统不是Linux,那么OSYS = 0x07D0
  1. If (_OSI ("Darwin"))
  2. {
  3.     Store (0x2710, OSYS)
  4. }
  5. ElseIf (_OSI ("Linux"))
  6. {
  7.     Store (0x03E8, OSYS)
  8. }
  9. Else
  10. {
  11.     Store(0x07D0, OSYS)
  12. }
复制代码
3、Switch, Case, Defaule, BreakPoint示例
  1. Switch(Arg2)
  2. {
  3.     Case(1)
  4.     {
  5. If(LEqual(1, Arg1)
  6. {
  7.     Return (1)
  8. }
  9. BreakPoint
  10.     }
  11.     Case(2)
  12.     {
  13.         ....
  14.         Return (2)
  15.     }
  16.     Default
  17.     {
  18.         BreakPoint
  19.     }
  20. }
复制代码
Switch可以看做是一系列If....Else的集合。BreakPoint相当于断点,意味着退出当前Swtich
(二)循环控制While,Break,Continue以及暂停Stall示例
  1. Store(10, Local0)
  2. While (LAnd (0x00, Local0))
  3. {
  4.     Decrement (Local0)
  5.     Stall (32)
  6. }
复制代码
Local0等于10,如果Local0逻辑于0不为真,Local0自减1,暂停32us,所以这段代码延时10 * 32 = 320 us。

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

查看全部评分

头像被屏蔽

Rank: 2Rank: 2

UID
1535799
帖子
218
PB币
0
贡献
0
技术
1
活跃
1
沙发
发表于 2011-11-21 14:19:55 IP属地贵州
提示: 作者被禁止或删除 内容自动屏蔽

图书管理员

Rank: 7Rank: 7Rank: 7

UID
342948
帖子
516
PB币
553
贡献
0
技术
93
活跃
97

8周年庆典勋章

板凳
发表于 2011-11-21 15:36:13 IP属地香港
mark,回去要研究下

Rank: 7Rank: 7Rank: 7

UID
934187
帖子
401
PB币
127
贡献
0
技术
0
活跃
47

7周年庆典勋章 8周年庆典勋章

4F
发表于 2011-11-21 15:37:50 IP属地广东
看着就是像看天书啊

Rank: 5Rank: 5Rank: 5

UID
1701553
帖子
590
PB币
107
贡献
0
技术
4
活跃
367
5F
发表于 2011-11-21 16:16:21 IP属地河北
深入研究

Rank: 7Rank: 7Rank: 7

UID
1587094
帖子
839
PB币
2
贡献
0
技术
9
活跃
760
6F
发表于 2011-11-21 16:31:28 IP属地浙江
恩 谢谢 有时间慢慢研究下  

Eh...

Rank: 7Rank: 7Rank: 7

UID
2024305
帖子
374
PB币
1054
贡献
0
技术
24
活跃
192

7周年庆典勋章

7F
发表于 2011-11-21 16:32:51 IP属地新加坡
mark mark。。

Rank: 2Rank: 2

UID
2154565
帖子
469
PB币
315
贡献
0
技术
1
活跃
583
8F
发表于 2011-11-21 16:33:33 IP属地广东
比较难懂,只能膜拜。。。

Rank: 7Rank: 7Rank: 7

UID
834306
帖子
2140
PB币
2014
贡献
0
技术
70
活跃
1985
9F
发表于 2011-11-21 16:35:44 IP属地上海
太高深了~~对不懂编程的人而言 真的很难理解。。只是最多知道一个顺序。。起码在编辑DSDT的时候 不会乱找。

Rank: 2Rank: 2

UID
1841834
帖子
145
PB币
1
贡献
0
技术
0
活跃
7
10F
发表于 2011-11-21 22:17:49 IP属地北京
这个要顶,感谢楼主分享知识

神仙

Rank: 2Rank: 2

UID
761895
帖子
427
PB币
946
贡献
0
技术
11
活跃
164

7周年庆典勋章

11F
发表于 2011-11-21 23:31:40 IP属地北京
谢谢楼主为大家分享知识 希望楼主再接再厉 谢谢

Rank: 5Rank: 5Rank: 5

UID
1330092
帖子
257
PB币
1247
贡献
0
技术
14
活跃
59
12F
发表于 2011-11-21 23:48:31 IP属地天津
好在学过C语言,语法还看得懂

Rank: 2Rank: 2

UID
1447955
帖子
326
PB币
339
贡献
0
技术
0
活跃
57
13F
发表于 2011-11-21 23:53:03 IP属地河北
这个要顶,感谢楼主分享知识

Rank: 2Rank: 2

UID
247257
帖子
116
PB币
1791
贡献
0
技术
0
活跃
25
14F
发表于 2011-11-22 00:01:30 IP属地江苏
感谢楼主分享

UID
420320
帖子
220
PB币
1776
贡献
0
技术
30
活跃
8
15F
发表于 2011-11-22 00:18:00 IP属地广东
又出了一个高人呀!学习中!!!

Rank: 5Rank: 5Rank: 5

UID
734355
帖子
973
PB币
1403
贡献
0
技术
7
活跃
141
16F
发表于 2011-11-22 00:23:37 IP属地江西
谢谢,语法蛮简洁,不过如果采用C Style就更好了

Rank: 9

UID
348940
帖子
3379
PB币
535
贡献
0
技术
214
活跃
3182

7周年庆典勋章

17F
发表于 2011-11-22 00:39:25 IP属地贵州 来自手机
好东西 可惜原来就没有学编程

Rank: 9

UID
893146
帖子
2438
PB币
7527
贡献
0
技术
33
活跃
1227
18F
发表于 2011-11-22 01:42:07 IP属地湖南
技术帖一定要支持,先收藏慢慢学。

Rank: 5Rank: 5Rank: 5

UID
1552532
帖子
628
PB币
937
贡献
0
技术
3
活跃
203
19F
发表于 2011-11-22 06:15:39 IP属地广东
好好学习一下,受益非浅啊

Rank: 2Rank: 2

UID
1990963
帖子
271
PB币
498
贡献
0
技术
3
活跃
136
20F
发表于 2011-11-22 08:21:08 IP属地北京
支持楼主!期待看到dsdt错误修改篇!呵呵。
回顶部
Copyright (C) 2005-2024 pcbeta.com, All rights reserved
Powered by Discuz!  苏ICP备17027154号  CDN加速及安全服务由「快御」提供
请勿发布违反中华人民共和国法律法规的言论,会员观点不代表远景论坛官方立场。
远景在线 | 远景论坛 | 苹果论坛 | Win11论坛 | Win10论坛 | Win8论坛 | Win7论坛 | WP论坛 | Office论坛