2024-12-23
- 参考
ACPI AML Runtime Debugger in Ubuntu 18.04 (x64)
- 之前一直以为ACPI是无法加打印的,但是在写ASL的过程中遇到了一些难于解决的问题,经过搜索后有了下面这篇文章。
- 要启用AML的打印,需要在编译内核时指定
CONFIG_ACPI_DEBUGGER=y
这个参数,否则是无法打印的,不过ubuntu在Ubuntu 18.04 (x64)之后就默认设置了这个参数,所以可以我们可以使用ubuntu系统来做AML的调试。下面所有的代码调试都是在ubuntu server 22.04.5上实现。
环境配置
#
- 要进行ACPI调试前需要安装acpidbg工具,该工具需要联网下载,但是我的调试服务器没办法联网,所以现在本地搭建了一个一样的虚拟机,通过虚拟机下载相应的deb包,随后拷到服务器上安装。
- 安装虚拟机过程略过,下面说一下虚拟机的网络配置,virtualbox默认会启动NAT网络地址转换,NAT能让虚拟机连上外网,但是无法通过SSH连上虚拟机;我们需要启用一个仅主机网络(相当于在物理机上创建了一个virtualbox专用的虚拟网卡),通过此虚拟网卡连接到虚拟机中。此虚拟网卡可以在virtualbox中配置IP地址。
-

-

- 随后进入到虚拟机的/etc/netplan中,创建文件
99_config.yaml
,填充如下内容(详细可参考
Configuring networks|Ubuntu)
network:
version: 2
renderer: networkd
ethernets:
enp0s8:
#IP配置取决于当前virtualbox总配置的IP地址
addresses:
- "192.168.168.168/24"
enp0s3:
#virtualbox nat,下面这些信息直接填照抄即可。
addresses:
- "10.0.2.15/24"
nameservers:
addresses: [8.8.8.8]
routes:
- to: default
via: 10.0.2.2
- 随后执行
netplan apply
让网络配置生效,此时就可以通过ssh连接到虚拟机内部了。
- 通过ssh连接后,通过如下命令下载相应的deb包,执行完后,deb包会被下载到
/var/cache/apt/archives
目录下,将该目录下的deb包打包传递到服务器上安装即可。
apt install linux-tools-`uname -r` linux-tools-generic --download-only
ACPI Debug
#
- 按照如下Printf的格式加入打印信息到ASL中,%o会被替换成后面相应的变量。
Method (_SUN, 0, NotSerialized) // _SUN: Slot User Number
{
Printf("VendorId = %o, DeviceId = %o, Slot = %o", VEND, DEVI, SLTN)
Return (SLTN)
}
- 随后编译烧入BIOS后,进入服务器的OS中,执行
acpidbg
,就可以进行调试了。acpidbg
常用的命令如namespace
、paths
、execute
。
namespace
会打印出ACPI的层级关系,如下图所示
root@server:~# acpidbg
- namespace
ACPI Namespace (from Namespace Root):
0 _GPE Scope 0000000008fab98e 000
0 _PR_ Scope 000000005953797b 000
1 C000 Processor 00000000a1ac5d21 01A ID 00 Len 06 Addr 0000000000000810
2 _PCT Package 00000000a7326f94 01B Elements 02
2 _PSS Package 0000000046ef281e 01B Elements 03
2 XPSS Package 000000005f13ae73 01B Elements 03
2 _PSD Package 000000009366b23a 01B Elements 01
2 PPCV Integer 000000009ee3a624 01B = 0000000000000000
2 _PPC Method 000000007965a545 01B Args 0 Len 0005 Aml 00000000be65bdfb
1 C001 Processor 000000005eb2da62 01A ID 01 Len 06 Addr 0000000000000810
2 _PCT Package 00000000ee112324 01B Elements 02
2 _PSS Package 0000000091ffd188 01B Elements 03
2 XPSS Package 00000000fb1c13d0 01B Elements 03
2 _PSD Package 0000000039eb741a 01B Elements 01
2 PPCV Integer 00000000df6eb317 01B = 0000000000000000
2 _PPC Method 000000000665d99d 01B Args 0 Len 0005 Aml 00000000fdc3368c
1 C002 Processor 00000000bfa4f34a 01A ID 02 Len 06 Addr 0000000000000810
paths
会打印出namespace objects的全路径名
#从左到右依次是层级、Object类型以及全路径名
3 Device _SB.S0D2.D2C0
4 Integer _SB.S0D2.D2C0._ADR
4 Method _SB.S0D2.D2C0._PRW
4 Method _SB.S0D2.D2C0._PRT
4 Region _SB.S0D2.D2C0.K1PC
4 RegionField _SB.S0D2.D2C0.K1SL
4 Device _SB.S0D2.D2C0.BRG1
5 Integer _SB.S0D2.D2C0.BRG1._ADR
5 Device _SB.S0D2.D2C0.BRG1.BRG2
6 Integer _SB.S0D2.D2C0.BRG1.BRG2._ADR
6 Device _SB.S0D2.D2C0.BRG1.BRG2.BRG3
7 Integer _SB.S0D2.D2C0.BRG1.BRG2.BRG3._ADR
7 Region _SB.S0D2.D2C0.BRG1.BRG2.BRG3.PP8C
7 RegionField _SB.S0D2.D2C0.BRG1.BRG2.BRG3.VEND
7 RegionField _SB.S0D2.D2C0.BRG1.BRG2.BRG3.DEVI
7 Method _SB.S0D2.D2C0.BRG1.BRG2.BRG3._SUN
3 Device _SB.S0D2.D2C1
4 Integer _SB.S0D2.D2C1._ADR
- 如果我们需要查看一个Field、Integer或者Method的执行结果,可以使用
execute
命令。
#查看_ADR的值
- execute _SB.S0D2.D2C0._ADR
Evaluating \_SB.S0D2.D2C0._ADR
Evaluation of \_SB.S0D2.D2C0._ADR returned object 000000003e779e35, external buffer length 18
[Integer] = 0000000000030001
#查看_SUN method的执行结果
- execute _SB.S0D2.D2C0.BRG1.BRG2.BRG3._SUN
Evaluating \_SB.S0D2.D2C0.BRG1.BRG2.BRG3._SUN
ACPI Debug: "VendorId = 0000000000001D94, DeviceId = 0000000000006210, Slot = 0000000000000002"
Evaluation of \_SB.S0D2.D2C0.BRG1.BRG2.BRG3._SUN returned object 000000003e779e35, external buffer length 18
[Integer] = 0000000000000002
#查看RegionField的值
- execute _SB.S0D2.D2C0.BRG1.BRG2.BRG3.VEND
Evaluating \_SB.S0D2.D2C0.BRG1.BRG2.BRG3.VEND
Evaluation of \_SB.S0D2.D2C0.BRG1.BRG2.BRG3.VEND returned object 0000000066540b46, external buffer length 18
[Integer] = 0000000000001D94
其他
#
- 如果需要在dmesg中查看ASL中增加的打印,可以修改
/etc/default/grub
文件,加入如下配置信息(具体含义可以参考
ACPI Debug Output),并执行update-grub
让其生效,随后重启就能在dmesg中看到ASL中的打印信息了。
GRUB_CMDLINE_LINUX_DEFAULT="acpi.debug_layer=0xFFFFFFFF acpi.debug_level=0x2"