自己动手写DSDT系列教程1-ASL(ACPI Source Language)基础篇
寫(xiě)在前面的話,鄙人不是一個(gè)主板BIOS開(kāi)發(fā)工作者,以下對(duì)ASL的理解僅僅來(lái)源于http://www.acpi.info/上的ACPI Specification文檔。因此難免會(huì)出現(xiàn)不少錯(cuò)誤的理解,以及錯(cuò)誤的觀點(diǎn),希望大家諒解以及糾正。
? ? 首先,不得不說(shuō)一下DSDT(Differentiated System Description Table)。什么是DSDT呢?其實(shí)它屬于ACPI其中的一個(gè)表格,而ACPI是Advanced Configuration & Power Interface的縮寫(xiě),高級(jí)配置和電源接口,從文字上就可以理解ACPI是一系列的接口,這個(gè)接口包含了很多表格,所以DSDT即是其中的一張表格同時(shí)也是一些接口。所以不難想象ACPI主要的功能就是提供操作系統(tǒng)一些服務(wù)以及提供一些訊息給操作系統(tǒng)使用。DSDT自然也不例外。ACPI的一個(gè)特色就是專有一門(mén)語(yǔ)言來(lái)編寫(xiě)ACPI的那些表格。它就是ASL(ACPI Source Language)也就是這盤(pán)文章的主角,ASL經(jīng)過(guò)編譯器編譯后,就變成了AML(ACPI Machine Language),然后由操作系統(tǒng)來(lái)執(zhí)行。既然ASL是一門(mén)語(yǔ)言,那就有它的準(zhǔn)則。
ASL準(zhǔn)則:
1、變量命名不超過(guò)4個(gè)字符,且不能以數(shù)字開(kāi)頭。聯(lián)想一下看到過(guò)的DSDT代碼看看,絕對(duì)不會(huì)超過(guò)。
2、Scope形成作用域,概念類似于數(shù)學(xué)中的集合{}。有且僅有一個(gè)根作用域,所以DSDT都以
DefinitionBlock ("xxxx", "DSDT", 0x02, "xxxx", "xxxx", xxxx)
{
開(kāi)始,同時(shí)以
}
結(jié)束。這個(gè)就是根作用域。xxxx參數(shù)依次表示輸出文件名、OEMID、表ID、OEM版本。第三個(gè)參數(shù)根據(jù)第二個(gè)參數(shù)指定,如上面所示。如果是"DSDT"就一定是0x02,其他參數(shù)都可以自由修改。
3、以“_”字符開(kāi)頭的函數(shù)和變量都是系統(tǒng)保留的,這就是為什么反編譯某些AML以后得到的ASL出現(xiàn)_T_X,重新編譯的時(shí)候會(huì)出現(xiàn)警告。
4、Method定義函數(shù),函數(shù)可以定義在Device下或者Scope下,但是不能脫離Scope定義單獨(dú)的函數(shù),所以不會(huì)有這種情況出現(xiàn)。
Method (xxxx, 0, NotSerialized)
{
......
}
DefinitionBlock ("xxxx", "DSDT", 0x02, "xxxx", "xxxx", xxxx)
{
......
}
5、根作用域下有\(zhòng)_GPE,\_PR,\_SB,\_SI,\_TZ五個(gè)作用域。\_GPE就是ACPI的事件處理,\_PR處理器,\_SB所有的設(shè)備和總線。\_SI系統(tǒng)指示燈。_TZ熱區(qū),用于讀取某些溫度。不同屬性的東西放在對(duì)應(yīng)的作用域下。例如:
設(shè)備Device (PCI0)放在Scope (\_SB)里面
Scope (\_SB)
{
??? Device (PCI0)
??? {
??????? ....
??? }
??? ....
}
CPU相關(guān)的信息放在Scope (_PR)
Scope (_PR)
{
??? Processor (CPU0, 0x00, 0x00000410, 0x06)
??? {
??????? ....
??? }
??? ....
}
Scope (_GPE)放著相關(guān)的事件處理
Scope (_GPE)
{
??? Method (_L0D, 0, NotSerialized)
??? {
??????? ....
??? }
??? ....
}
乍一看不是函數(shù)嗎?當(dāng)然函數(shù)也可以放在這里。但是請(qǐng)注意函數(shù)名“_”開(kāi)頭,是系統(tǒng)保留的函數(shù)。
6、Device(xxxx)也可看做是一個(gè)作用域
7、符號(hào)“\”引用根作用域,“^”引用上級(jí)作用域
8、ASL中沒(méi)有運(yùn)算符,+-*/=是不會(huì)出現(xiàn)了,但是有等價(jià)的函數(shù)。
9、函數(shù)最多可以傳遞8個(gè)參數(shù),在函數(shù)里用Arg0~Arg7表示,不可以自定義。
10、函數(shù)最多可以用8個(gè)局部變量,用Local0~Local7,不用定義,但是需要初始化才能使用,也就是一定要有一次賦值操作。
ASL常用的數(shù)據(jù)類型:
Integer(整數(shù))、String(字符串)、Event(事件)、Buffer(數(shù)組)、Package(對(duì)象集合)
ASL定義變量:
例如:
Name(TEST,0)//定義一個(gè)整數(shù)
Name(MSTR,"ASL")//定義一個(gè)字符串
Name (_PRW, Package (0x02)
??????????????? {
??????????????????? 0x0D,?
??????????????????? 0x03
??????????????? })
//定義一個(gè)Package
可以發(fā)現(xiàn)定義變量的時(shí)候不需要顯式聲明其類型
ASL賦值方法:
有且僅有一個(gè),Store(a,b)如
Store(0,Local0)//Local0=0
Store(Local0,Local1)//Local0=Local1
ASL運(yùn)算函數(shù):
上面提到ASL沒(méi)有運(yùn)算符號(hào),但是有運(yùn)算函數(shù)
Add 整數(shù)相加
And 整數(shù)于
Decrement 整數(shù)自減1
Divide 整數(shù)除法
Increment 整數(shù)自增1
Mod 整數(shù)求余
Multiply 整數(shù)相乘
ShiftLeft 左移
ShiftRight 右移
Subtract 整數(shù)減法
Or 或
Not 取反
Nor 異或
等等,具體請(qǐng)查閱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邏輯運(yùn)算:
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)
不難發(fā)現(xiàn)邏輯運(yùn)算只會(huì)有兩種結(jié)果0或者1。
ASL函數(shù)的定義:
1、定義函數(shù)
Method(TEST)
{}
2、定義有兩個(gè)輸入?yún)?shù)的函數(shù),以及使用局部變量Local0~Local7
Method(MADD,2)
{
??? Store(Arg0, Local0)
??? Store(Arg1, Local1)
??? Add(Local0, Local1, Local0)
}
實(shí)現(xiàn)了兩個(gè)參數(shù)的加法運(yùn)算,因此傳入的參數(shù)一定要隱式整形數(shù)。
3、定義帶返回值的函數(shù)
Method(MADD,2)
{
??? Store(Arg0, Local0)
??? Store(Arg1, Local1)
??? Add(Local0, Local1, Local0)
??? Return (Local0)
}
例子為自定義加法的實(shí)現(xiàn)。函數(shù)實(shí)現(xiàn)如同系統(tǒng)函數(shù)Add一樣的相加
Store(MADD(1,2), Local0) //Local0 = 1 + 2
4、定義可序列化的函數(shù)
Method(MADD, 2, Serialized)
{
Store(Arg0, Local0)
Store(Arg1, Local1)
Add(Local0, Local1, Local0)
Return (Local0)
}
這個(gè)有點(diǎn)類似于多線程同步的概念,也就是說(shuō),當(dāng)函數(shù)聲明為Serialized,內(nèi)存中僅能存在一個(gè)實(shí)例。一般應(yīng)用在函數(shù)中創(chuàng)建一個(gè)對(duì)象。應(yīng)用舉例說(shuō)明:
Method(TEST, Serialized)
{
??? Name(MSTR,"I will sucess"
}
如果這樣子聲明TEST這個(gè)函數(shù),那么在兩個(gè)地方同時(shí)調(diào)用這個(gè)函數(shù)
Device (Dev1)
{
???? TEST()
}
Device (Dev2)
{
???? TEST()
}
如果先執(zhí)行Dev1的TEST,Dev2中的TEST將等待Dev1中的TEST函數(shù)執(zhí)行完畢再執(zhí)行。如果聲明為
Method(TEST, NotSerialized)
{
Name(MSTR,"I will sucess"
}
那么將在其中一個(gè)Devx調(diào)用TEST的時(shí)候,另外一個(gè)調(diào)用失敗,當(dāng)它試圖創(chuàng)建相同的字符串MSTR的時(shí)候。
ASL流程控制:
和常見(jiàn)的高級(jí)語(yǔ)言一樣,ASL也有與之對(duì)應(yīng)的控制流程語(yǔ)句。
Break
BreakPoint
Case
Continue
Default
Else
ElseIf
If
Return
Stall
Switch
While
(一)分支控制If, ElseIf, Else, Switch, Case
1、If用法介紹
例如下面的語(yǔ)句判斷一下當(dāng)前系統(tǒng)的接口是不是Darwin,如果是把OSYS = 0x2710
If (_OSI ("Darwin"))
{
??? Store (0x2710, OSYS)
}
2、ElseIf、Else用法介紹,如果系統(tǒng)結(jié)構(gòu)不是Darwin,另外如果系統(tǒng)不是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相當(dāng)于斷點(diǎn),意味著退出當(dāng)前Swtich
(二)循環(huán)控制While,Break,Continue以及暫停Stall示例
Store(10, Local0)
While (LAnd (0x00, Local0))
{
??? Decrement (Local0)
??? Stall (32)
}
Local0等于10,如果Local0邏輯于0不為真,Local0自減1,暫停32us,所以這段代碼延時(shí)10 * 32 = 320 us。
累了,今天就寫(xiě)到這里,有了這些基礎(chǔ),鄙人覺(jué)得現(xiàn)在大部分論壇壇友對(duì)著DSDT的時(shí)候就不會(huì)是發(fā)呆又發(fā)呆,至少可以明白些少語(yǔ)句了。
原文出自:http://bbs.pcbeta.com/viewthread-944566-1-1.html
總結(jié)
以上是生活随笔為你收集整理的自己动手写DSDT系列教程1-ASL(ACPI Source Language)基础篇的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: POE 供电设备原理详解
- 下一篇: 代码工具---长链接转换短链接