【图解】替换 Windows ACPI Table的方法

本文介绍一种在没有BIOS代码的情况下,修改 ACPI Table 的方法。实际上这种方法已经使用很多很多年了,作为一种测试的方法是非常有效的。
使用到的工具一个是asl 这是微软 wdk 里面带的,用来 dump 和 load 系统acpi table 的;另外一个是 iasl, 这是 acpica 提供的工具,用来编译和反编译 asl 。特别需要注意的问题是,我在实践中发现 iasl 不同版本之间差别很大,如果你在使用中发现编译或者反编译错误非常多,那么最好多尝试几个版本,如果有条件最好直接使用Build 你BIOS的版本。
原理:Windows每次使用的 ACPI table 不是直接从内存读取的,而是缓冲在系统注册表上,因此替换这个注册表里面的就可以取得替换 ACPI Table的效果。
操作:

1. 在 console 下面(需要 Administrator权限),使用命令 asl.exe /tab=DSDT /c

2. 反编译抓下来的 DSDT0000.bin ,使用命令 iasl2016 –ve DSDT0000.bin

虽然报错了,但是还是生成了 dsdt0000.dsl

3. 将生成的 DSDT0000.DSL 改名为 dsdt.sdl,再重新编译之 ,命令是 Iasl2016.exe –ve DSDT.dsl

编译直接出错,修改这个错误(单纯来说,我这次碰到的问题是因为 extern 了 BNUM 和 RTIP,但是后面又重新定义了这两个名字所以会有冲突,修改方法是去掉 extern 的 BNUM和RTIP)

修改之后就可以正常编译了
4. 加入一个我们自定义的设备做为标记,加入的位置在 EC 下面,这样便于观看。加入的代码如下:

            Device (LABZ)
            {
                Name (_HID, EisaId ("LAB33D6") /* Intel Virtual Buttons Device */)  // _HID: Hardware ID
                Method (_STA, 0, Serialized)  // _STA: Status
                {
                    Return (0x0F)
                }

            }

再次编译,

5. 将编译后的结果加入系统中,命令是 asl /loadtable dsdt.aml

6. 重启之后,设备管理器中还是没有变化。需要再设置打开TestMode。 方法是在 console 下面使用
Bcdedit /set testsigning on

7.重启之后就可以在设备管理器中看到我们加入的设备了
加入之前

修改之后

上面的 Unknown device就是我们新加入的设备,设备属性

8. 删除加载的 dsdt 的方法是 asl /loadtable dsdt.aml –d 重启之后即可恢复

changeacpi

从原理上说,Windows会将 DSDT Table “缓存” 在注册表中,在开机的过程中不会去内存解析DSDT而是直接使用缓存的。因此,我们可以通过上面的方法来加入我们需要的代码。

=====================================================

2024年5月20日 在 Windows 11 的虚拟机上测试过,上述方法仍然有效。

《【图解】替换 Windows ACPI Table的方法》有2个想法

  1. 我正在尝试修改我的ACPI表,但是在加载修改后的aml文件重启时,显示 “自动修复” 并无法进入windows 系统,需要在引导中选择 "修复无法进入系统"(大概是这个选项) 才能进入系统,在设备管理器中也无法看到我插入的代码产生的预期影响(理论上会增加一个大容量内存)。这是BIOS的设置问题,还是编译的aml文件不正确?以下是我插入的代码
    QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
    0x0000000000000000, // Granularity
    0x0000000C20000000, // Range Minimum, set it to 48.5GB
    0x000000122FFFFFFF, // Range Maximum, set it to 72.75GB
    0x0000000000000000, // Translation Offset
    0x0000000610000000, // Length calculated by Range Max - Range Min + 1. 24.25GB
    ,, , AddressRangeMemory, TypeStatic)

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注