[DSDT]总结一下DSDT定制中的一些技巧

[DSDT]总结一下DSDT定制中的一些技巧

查看: 6645|回复: 51

[DSDT]

总结一下DSDT定制中的一些技巧

[复制链接]

wangdongfreesky

wangdongfreesky

当前离线

UID4887081

最后登录1970-1-1

阅读权限20

精华

主题

回帖0

积分158

PB币

威望

贡献

技术

活跃

发消息

电梯直达

楼主

wangdongfreesky

发表于 2023-3-16 13:39

|

只看该作者

|倒序浏览

|阅读模式

玩儿黑苹果,免不了和ACPI打交道,也就是大家常说的DSDT和SSDT,在这里我总结一下我在编辑ssdt中的一些经验和技巧

一、系统判断

这个是大家都知道的,就是我们在编写ssdt时都会有这样一段代码

If (_OSI ("Darwin"))

这个代码的作用就是做系统判断,让代码只在黑苹果上生效,不会影响win系统。

一般的,这样判断,都会写在函数里,请看下面代码

DefinitionBlock ("", "SSDT", 2, "OCLT", "MCHC", 0)

{

External (_SB.PCI0, DeviceObj)

Scope (_SB.PCI0)

{

Device (MCHC)

{

Name (_ADR, Zero)

Method (_STA, 0, NotSerialized)

{

If (_OSI ("Darwin"))

{

Return (0x0F)

}

Else

{

Return (Zero)

}

}

}

}

}

但是呢,我会这样写:请看我的代码

DefinitionBlock ("", "SSDT", 2, "OCLT", "MCHC", 0x00000000){

External (_SB_.PCI0, DeviceObj)

If (_OSI ("Darwin"))

{

Scope (_SB.PCI0)

{

Device (MCHC)

{

Name (_ADR, Zero) // _ADR: Address

Name (_STA, 0x0F) // _STA: Status

}

}

}

}

我用的方法是将系统判断直接放在代码的最外面,

这样能最大程度的减少代码对win的影响,而且能够简化代码,使代码阅读更清晰

这里还有一个技巧,将函数直接定义为变量,

下面的代码

Method (_PRW, 0, NotSerialized) // _PRW: Power Resources for Wake

{

Return (Package (0x02)

{

0x19,

0x04

})

}

可以写成

Name (_PRW, Package (0x02)

{

0x19,

0x04

})

二、用Ioreg来验证ssdt是否生效

编写ssdt,好多时候我们是为了仿冒设备,那你怎么知道你仿冒的设备是否有用?一般在苹果系统中必要的设备都会加载相应的Kext,

IOreg的全称是IORegistryExplorer

他的功能是查看系统 I/O 信息以及驱动和设备的附属关系

如果你仿冒的设备被成功加载,那么该设备名下是有相应的子项存在的,并且在该设备的右面是有你定义的设备属性的

三、利用Hackintool的计算器来给设备改名

有些时候,DSDT中的设备需要改名,改成MacOS系统中常用的设备名

有些时候,我们还需要对系统保留的带_开头的函数进行重新命名使它失效,进而加载我们重新编写的函数,比如_PTS、_PRW、_DSM等

需要注意的是DSDT中设备和函数的命名都是四个字节,比如XHC实际上是XHC_

这里我们利用Hackintool可以很方便的就能计算出相关的设备名或函数名的十六进制代码,可以很方便的通过打ACPI补丁的方式就可以实现对设备或函数的重新命名

三、利用Hex Fiend活用noop来直接修改部分dsdt

在ssdt编写中,noop这个关键字没有任何作用他的作用就是补齐代码

某个设备,有这样一段代码

Device(GTTY)

Name (_STA,0x0F) // _STA: Status

我需要让它返回Zero

但是_STA是多个设备都拥有的函数,每个设备的_STA都不一样,如果贸然使用改名的方法,需要对所有设备的_STA函数重写,牵涉巨大,那么应该怎么做呢?我只需要对这个GTTY设备的_STA函数打补丁,那么我们扩大查找范围把GTTY和_STA都包含进去,那么不就唯一了吗?这样这块补丁不就精确的打到了它应该存在的位置上了吗?

但是还有一个问题

在二进制代码中Zero和0x0F的长度是不一样的为了补齐长度我会把它变成

Name (_STA,Zero) // _STA: Status

noop

上面的代码很简单,很好修补是不是?但是下面这段代码

Method (_STA, 0, NotSerialized) // _STA: Status

{

If ((UM00 == 0x03))

{

If ((UP00 == 0x02))

{

UP00 = UAPG (UM00, UP00, UC00)

}

Return (0x0F)

}

Return (0x03)

}

我需要它返回Zero该怎么办呢?

我会把它单独复制出来做成一个aml

DefinitionBlock ("", "SSDT", 2, "WDOC", "DEVICE", 0x00000000)

{

Method (_STA, 0, NotSerialized) // _STA: Status

{

If ((UM00 == 0x03))

{

If ((UP00 == 0x02))

{

UP00 = UAPG (UM00, UP00, UC00)

}

Return (0x0F)

}

Return (0x03)

}

}

当然这样编译肯定是不通过啦

所以我要修正这段代码缺失的部分,很显然不通过,是因为存在UM00、UP00、UC00三个变量和UAPG一个函数,

DefinitionBlock ("", "SSDT", 2, "WDOC", "DEVICE", 0x00000000)

{

External (UM00, IntObj)

External (UP00, IntObj)

External (UC00, IntObj)

Method (UAPG, 3, NotSerialized)

{

Return (Zero)

}

Method (_STA, 0, NotSerialized) // _STA: Status

{

If ((UM00 == 0x03))

{

If ((UP00 == 0x02))

{

UP00 = UAPG (UM00, UP00, UC00)

}

Return (0x0F)

}

Return (0x03)

}

}

OK,这样不就编译通过了吗?我这样做的目的就是为了获得函数_STA的二进制代码,编译为AML,命名为1.AML

接下来我把这个AML另存为一个副本,这个副本命名为2.AML,打开这个副本修改为

DefinitionBlock ("", "SSDT", 2, "WDOC", "DEVICE", 0x00000000)

{

External (UM00, IntObj)

External (UP00, IntObj)

External (UC00, IntObj)

Method (UAPG, 3, NotSerialized)

{

Return (Zero)

}

Method (_STA, 0, NotSerialized) // _STA: Status

{

noop

若干个noop

noop

Return (Zero)

}

}

然后保存后,用Hex find这个软件打开,直到你填充的noop后这个副本和之前的原本长度一致

然后分别在两个AML中查找_STA,从_STA开始到结尾的代码,在1.AML中就是你要查找的代码,而在2.AML中就是你要替换的代码,这样加上这段补丁,就实现了对DSDT的修改

收藏29

分享

回复

使用道具

举报

提升卡

沉默卡

喧嚣卡

变色卡

千斤顶

总是晴天

总是晴天

当前离线

UID4847149

最后登录1970-1-1

阅读权限30

精华

主题

回帖0

积分286

PB币

威望

贡献

技术

活跃

发消息

沙发

总是晴天

发表于 2023-3-18 11:58

|

只看该作者

字都认识,意思呢也都明白,就是不会操作。

回复

使用道具

举报

chekaiming

chekaiming

当前离线

UID1969174

最后登录1970-1-1

阅读权限0

精华

主题

回帖0

积分193

PB币

威望

贡献

技术

活跃

发消息

头像被屏蔽

板凳

chekaiming

发表于 2023-3-18 12:11

|

只看该作者

提示: 作者被禁止或删除 内容自动屏蔽

回复

使用道具

举报

duwid

duwid

当前离线

UID4447262

最后登录1970-1-1

阅读权限40

精华

主题

回帖0

积分1207

PB币

威望

贡献

技术

活跃

发消息

4F

duwid

发表于 2023-3-18 13:54

|

只看该作者

大佬这返回的0x19 0x04这是怎么得来的呢

回复

使用道具

举报

wangdongfreesky

wangdongfreesky

当前离线

UID4887081

最后登录1970-1-1

阅读权限20

精华

主题

回帖0

积分158

PB币

威望

贡献

技术

活跃

发消息

5F

wangdongfreesky

楼主|

发表于 2023-3-18 16:14

|

只看该作者

本拉登他爹 发表于 2023-3-18 13:54

大佬这返回的0x19 0x04这是怎么得来的呢

一般是返回GPRW(0x19,0x04),然后你在看看GPRW函数的操作返回什么,经过各种判断和运算,最终,还是0x19 0x04

回复

使用道具

举报

wangdongfreesky

wangdongfreesky

当前离线

UID4887081

最后登录1970-1-1

阅读权限20

精华

主题

回帖0

积分158

PB币

威望

贡献

技术

活跃

发消息

6F

wangdongfreesky

楼主|

发表于 2023-3-18 16:51

|

只看该作者

为了让大家更明白,我给大家逐步演示

二、用Ioreg来验证ssdt中的设备加载情况,没有ssdt补丁,打开roreg我的设备是这样的

这表示HPET设备没有加载

出现了PCIXXXX,XXXX@X说明设备没有按照苹果的规范来命名

而且用hackintool也能查看到诸如PCIXXXX,XXXX@X的设备

同时,我的硬盘是橙色外置硬盘,这是因为GPP6下的设备PCI1e4b,1202@0没有正确的命名所导致的,虽然IONVMe控制器加载了,但我们仍然需要对它进行命名(命名和重命名的区别:命名是指设备没有名字,我们需要给他命名,一般用ssdt。重命名是设备有名字但是不是macos的命名方式,导致系统不识别不加载相应的驱动,我们需要给它改名字,也就是重命名,一般用补丁改名)

命名的ssdt很简单,只需要对照白果的ioreg找到正确的名字,然后将_ADR给定一个正确的地址就行了,(有的是仿冒不存在的设备,按照标准的地址即可),那么这个地址哪里来?(@后面的就是地址)

比如pci1e4b,1202@0他的地址就是GPP6下的Zero!

因此我做了如下的SSDT

If (_OSI ("Darwin"))

{

Name (HPET._CRS, ResourceTemplate () // _CRS: Current Resource Settings

{

IRQNoFlags ()

{0,8,11}

Memory32Fixed (ReadWrite,

0xFED00000, // Address Base

0x00000400, // Address Length

)

})

Scope (_SB.PCI0)

{

Device (GPP2.GIGE) //对应GPP2下的ethernet(这也是没有命名)

{

Name (_ADR, Zero) // _ADR: Address

}

Device (GPP3.ARPT) // 对应pci14e4,43a0@0

{

Name (_ADR, Zero) // _ADR: Address

}

Device (GPP6.DEV0) //pci1e4b,1202@0

{

Name (_ADR, Zero) // _ADR: Address

}

Device (GPP6.DEV1) //实际上GPP6下存在两个硬盘,只有插了另一块时才能显示pci1e4b,1202@1

{

Name (_ADR, One) // _ADR: Address

}

Device (LPCB.PMCR) //这个是节能五项的设备,不懂可一看一下oc-little

{

Name (_HID, EisaId ("APP9876")) // _HID: Hardware ID

Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings

{

Memory32Fixed (ReadWrite,

0xFE000000, // Address Base

0x00010000, // Address Length

)

})

}

Device (SBUS.BUS0) //加载SM总线的固定格式,没什么好说的,照做就行

{

Name (_CID, "smbus") // _CID: Compatible ID

Name (_ADR, Zero) // _ADR: Address

Device (DVL0)

{

Name (_ADR, 0x57) // _ADR: Address

Name (_CID, "diagsvault") // _CID: Compatible ID

Method (_DSM, 4, NotSerialized) // _DSM: Device-Specific Method

{

If (!Arg2)

{

Return (Buffer (One)

{

0x03 // .

})

}

Return (Package (0x02)

{

"address",

0x57

})

}

}

}

}

}

接下来,加载,加载完成后就会变成下面这样

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×

回复

使用道具

举报

wangdongfreesky

wangdongfreesky

当前离线

UID4887081

最后登录1970-1-1

阅读权限20

精华

主题

回帖0

积分158

PB币

威望

贡献

技术

活跃

发消息

7F

wangdongfreesky

楼主|

发表于 2023-3-18 17:02

|

只看该作者

下面这些是对设备的重命名

在我的机器里,AMD的APU和独显6600都被命名为了VGA,我需要把APU命名为IGPU,而独显命名为GFX0,由于二者都被命名为VGA,所以我要根据路径和所在打了多个补丁前三个是使用了路径,而后面的两个补丁包含了_ADR关键字,因为只有

Device ()

name (_ADR

这里才会单独使用VGA命名,为了区分

然后这个命名的ssdt加载后,IOReg就变成了这样

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×

回复

使用道具

举报

wangdongfreesky

wangdongfreesky

当前离线

UID4887081

最后登录1970-1-1

阅读权限20

精华

主题

回帖0

积分158

PB币

威望

贡献

技术

活跃

发消息

8F

wangdongfreesky

楼主|

发表于 2023-3-18 17:20

|

只看该作者

HPET设备正确加载,加载了AppleHPET驱动

设备命名正确实现内建

无线网卡设备命名正确实现内建

Nvme硬盘控制器命名正确,磁盘不再是橙色的外置磁盘,实现了内建

SM总线实现了加载

PCMR实现了加载AppleACPIPMC,节能出现五项

可见,当设备被正确命名后,要么会加载相关的KEXT,要么实现设备的内建,要么在该设备的ioreg属性栏中出现修正后的正确属性

比如USBX属性加载

Device (USBX)

{

Name (_ADR, Zero) // _ADR: Address

Method (_DSM, 4, NotSerialized) // _DSM: Device-Specific Method

{

If ((Arg2 == Zero))

{

Return (Buffer (One)

{

0x03 // .

})

}

Return (Package (0x08)

{

"kUSBSleepPowerSupply",

0x13EC,

"kUSBSleepPortCurrentLimit",

0x0834,

"kUSBWakePowerSupply",

0x13EC,

"kUSBWakePortCurrentLimit",

0x0834

})

}

}

正确加载后ioreg的AppleUSBHostResources属性中会出现相关属性

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×

回复

使用道具

举报

kyomio

kyomio

当前离线

UID4874811

最后登录1970-1-1

阅读权限10

精华

主题

回帖0

积分27

PB币

威望

贡献

技术

活跃

发消息

9F

kyomio

发表于 2023-3-18 20:09

|

只看该作者

不明觉厉,还需要学习。。。

回复

使用道具

举报

harryboy6537

harryboy6537

当前离线

UID1558559

最后登录1970-1-1

阅读权限20

精华

主题

回帖0

积分125

PB币

威望

贡献

技术

活跃

发消息

10F

harryboy6537

发表于 2023-3-18 20:18

|

只看该作者

字都认识,意思呢也都明白,就是不会操作。

回复

使用道具

举报

hello_limin

hello_limin

当前离线

UID789668

最后登录1970-1-1

阅读权限30

精华

主题

回帖0

积分204

PB币

威望

贡献

技术

活跃

发消息

11F

hello_limin

发表于 2023-3-18 20:22

|

只看该作者

谢谢楼主的分享

回复

使用道具

举报

庄森

庄森

当前离线

UID36772

最后登录1970-1-1

阅读权限30

精华

主题

回帖0

积分322

PB币

威望

贡献

技术

活跃

发消息

12F

庄森

发表于 2023-3-18 21:08

|

只看该作者

不明觉厉,还需要学习。。。

回复

使用道具

举报

wings110

wings110

当前离线

UID1482923

最后登录1970-1-1

阅读权限40

精华

主题

回帖0

积分656

PB币

威望

贡献

技术

活跃

发消息

13F

wings110

发表于 2023-3-19 08:26

来自手机

|

只看该作者

感谢分享,学习了

回复

使用道具

举报

ydhmq

ydhmq

当前离线

UID167086

最后登录1970-1-1

阅读权限40

精华

主题

回帖0

积分1143

PB币

威望

贡献

技术

活跃

发消息

14F

ydhmq

发表于 2023-3-19 08:51

来自手机

|

只看该作者

感谢分享,学习了

回复

使用道具

举报

tushendage

tushendage

当前离线

UID463044

最后登录1970-1-1

阅读权限50

精华

主题

回帖0

积分2054

PB币

威望

贡献

技术

活跃

发消息

15F

tushendage

发表于 2023-3-19 09:36

|

只看该作者

这是技术的东西了。

回复

使用道具

举报

Dynamix

Dynamix

当前离线

UID4732780

最后登录1970-1-1

阅读权限30

精华

主题

回帖0

积分484

PB币

威望

贡献

技术

活跃

发消息

16F

Dynamix

发表于 2023-3-19 10:25

|

只看该作者

本帖最后由 Dynamix 于 2023-3-19 10:26 编辑

本拉登他爹 发表于 2023-3-18 13:54

大佬这返回的0x19 0x04这是怎么得来的呢

看DSDT 你要处理那个设备的原始_PRW 返回值, _PRW 返回的是一个两个整数的对象数组 索引0 是GPEInfo 索引1 是 Lowest Sleep State ,

GpeInfo是固件里就定义好的 为设备的GPIO_SCI分配的一个事件号 用于管理设备的电源事件 例如 Intel平台 PCI设备通用目的事件号有两类 0x6D 和 0x69 分别对应PCH集成设备 和 PCIe Root Port 设备唤醒需要由ACPI通知 OSPM , Notify对应的设备对象则通过 GPEInfo可以在 \_GPE 下找到 管理 PCH集成设备的叫 _L6D 管理 PCIe Root Port的则叫 _L69 而 Lowest Sleep State则表示设备可以提供唤醒能力的最低睡眠等级 0/1/2/3/4 分别对应 _S1、_S2、_S3、_S4

点评

wangdongfreesky

牛逼,一针见血

发表于 2023-3-19 10:32

回复

使用道具

举报

wangdongfreesky

wangdongfreesky

当前离线

UID4887081

最后登录1970-1-1

阅读权限20

精华

主题

回帖0

积分158

PB币

威望

贡献

技术

活跃

发消息

17F

wangdongfreesky

楼主|

发表于 2023-3-19 10:32

|

只看该作者

Dynamix 发表于 2023-3-19 10:25

看DSDT 你要处理那个设备的原始_PRW 返回值, _PRW 返回的是一个两个整数的对象数组 索引0 是GPEInfo 索引 ...

大佬,这方面的知识您多讲讲呗,有关睡眠唤醒和PCH等一些知识

回复

使用道具

举报

Dynamix

Dynamix

当前离线

UID4732780

最后登录1970-1-1

阅读权限30

精华

主题

回帖0

积分484

PB币

威望

贡献

技术

活跃

发消息

18F

Dynamix

发表于 2023-3-19 10:35

|

只看该作者

wangdongfreesky 发表于 2023-3-18 16:51

为了让大家更明白,我给大家逐步演示

二、用Ioreg来验证ssdt中的设备加载情况,没有ssdt补丁,打开roreg我 ...

你的呢是AMD平台 我有个疑问 其实对于 AppleHPET个AppleACPIPMC 并不是为了加载而加载 你确定AMD平台 HPET的内存范围是_BAS FED00000h 吗, 你看一下DSDT里 HPET 资源模板的定义吧, 还有 PMCR 他的资源模板写的可是 ReadWrite 驱动可以读写指定内存范围 你确定 AMD的 PWRM内存起始和Intel一样都是 FE000000h吗 如果 FE000000h 是常驻内存里面有重要数据映射被 驱动错误更改是否会导致更严重的问题出现?

回复

使用道具

举报

Dynamix

Dynamix

当前离线

UID4732780

最后登录1970-1-1

阅读权限30

精华

主题

回帖0

积分484

PB币

威望

贡献

技术

活跃

发消息

19F

Dynamix

发表于 2023-3-19 10:43

|

只看该作者

还有个方法 其实ACPI Patch查找替换如果在 自定义SSDT中没有做回调势必会影响Windows 其实macOS 对于 _STA 方法支持结果覆写 就像那些在DSDT中的部分设备 _STA 没有返回 0的条件你可以用SSDT直接覆盖掉它的 _STA 的结果 在SSDT中把对应设备的 Method (_STA) 引用为 IntObj或者 UnknownObj 直接用赋值语法 比如 直接

_STA = 0

直接禁用设备也不会产生ACPI Error 也不用 ACPI Patch 查找替换

回复

使用道具

举报

wangdongfreesky

wangdongfreesky

当前离线

UID4887081

最后登录1970-1-1

阅读权限20

精华

主题

回帖0

积分158

PB币

威望

贡献

技术

活跃

发消息

20F

wangdongfreesky

楼主|

发表于 2023-3-19 10:45

|

只看该作者

Dynamix 发表于 2023-3-19 10:35

你的呢是AMD平台 我有个疑问 其实对于 AppleHPET个AppleACPIPMC 并不是为了加载而加载 你确定AMD平台 HPE ...

这个hpet是ssdttime生成的,就是irq补丁而加载的,实际不加载貌似没什么影响,

回复

使用道具

举报

相关推荐

频繁GC (Allocation Failure)及young gc时间过长分析 365bet游戏平台
天猫开店一个月要多少钱,天猫开个店铺多少钱 bt365手机版
ProfessionalC第四版资源介绍:深入C++高级编程的不二选择 365bet游戏平台