Tracking ACPI/ASL Using WinDbg . `. N9 t1 v) f# D1 {( L* Z
: Q/ ^0 {3 o1 H- l4 {1. Preface
+ R9 Q9 y6 k( E" U
1 [; x3 ?9 D/ |( A5 F0 sACPI是BIOS和OS之间沟通的主要手段,所以有些系统相关的问题,都跟ACPI asl code有很大的关系,如果能够直Debug ACPI asl code那将会对解决这类问题提供很好的帮助。这篇文章的目的就是讲解如何使用WinDbg实现ACPI/ASL code源码级别的调试。
- h; _+ C$ w8 R, ~4 f
9 D1 e6 d7 S& r" G4 }' r- T9 z0 S2. Configuration of Debugger & Debuggee
! b1 K) N. ~1 T7 c; k& P7 X7 g$ } A/ c9 a, k; Y
Debug ACPI 最好是双机调试,一台主机Debugger和一台目标机器Debuggee。WinDbg支援COM,1394,USB2.0三种不同的连接方式。它们的配置方法都大同小异,我使用的1394,所以我将介绍1394的配置方式。
! |" M& b$ L3 g7 e. M! n2 A2 }$ na)设置Debuggee为调试模式
3 \- b6 [ o! d/ P5 c启动Debuggee进入OS,点击开始菜单选择运行,然后输入msconfig然后选择BOOT.INIèAdvanced Optionsè/DEBUG剩下的具体方式如下图1所示,其中/CHANEL选择可以随便指定,但是要和Debugger端设置的要一致。7 e' ~8 `1 n. T
3 y8 G1 j8 @5 n! J9 S6 m* M8 r
" ?- ^/ O i( M, ?' ]图1
2 r* f, w( g+ F) e2 ?" W/ C/ `8 y. m
b)安装设置WinDbg/ e% e+ z, i( j" D) ~
; ]/ G+ U+ l; p: N8 \, |3 t# |
WinDbg是微软提供的免费的Debug工具(微软还是不错的J),它非常强大,可以调试各种程序包括ACPI,Driver,AP而且它甚至可以用于Windows OS Kernel Debug,据说微软自己也使用该程式辅助开发他们的OS, WinDbg在微软网站上有免费下载。如果你在别的机器上已经安装好了WinDbg,那么可以直接copy过来就能使用了。
" d' C5 k7 Y( L [. \& h8 b5 k8 G( \
c)安装Symbol File, S. W+ A( c/ r
3 Q' G( [: G* r' ~; b" U; [/ z H$ l& T
什么是symbol文件呢?Symbol文件包含了被调试程序的变量名称,函数名,入口地址以及代码行号等信息。通常以pdb为扩展名。为了能调试debuggee,debugger端使用的Symbol文件一定要和目标机上安装的操作系统的版本要一致。Symbol文件对于WinDbg来说是至关重要的,如果找不到正确的Symbol文件,调试功能就没法使用。安装完Symbol以后Ctrl + S设置WinDbg Symbol路径例如SRV*C:\Symbols*C:\WINNT\Symbols*http://msdl.microsoft.com/download/symbols。最好把微软的Symbols 服务器也写上这样比较保险。Windows的Symbol文件可以在微软网站上免费下载。: y6 M F4 t' C2 T. w2 D
& [5 E6 y) ]' H& E* |
d)安装Checked Acpi.sys0 e% E9 t2 ^/ Z6 R, ]
/ f' V* `' n2 W" K( S' s8 Y/ t
BIOS中的ASL code通过asl.exe这个程序转化为aml文件,进入OS以后,OS通过两个inbox的driver Acpi.sys Smbios.sys解释和执行aml code。而且微软还提供了一个调试工具专门用于调试aml code,它就是Microsoft AMLI Debugger。这个Debugger需要两部分配合才能工作,一部分内建于WinDbg,另一部分则需要Checked Acpi.sys。所以如果要调试ACPI asl code,就必须要安装checked Acpi.sys和Symbol文件一样Checked Acpi.sys一定要和目标机安装的操作系统版本要一致。替换debuggee的system32\drivers下的 Acpi.sys,一定要进入安全模式,如果不仅安全模式你会很惨哦J。, u" A; @0 }& K1 r3 B1 l* i; K
. N) I; n; E9 T* N5 v
e)Start Kernel Debug
1 r, V5 p. o7 a, g" C7 b/ Y打开WinDbg选择FileèKernel Debugè1394(channel 1)èOK
$ F* d9 g) c4 _+ L Q' r0 L如下图2所示:
+ r5 H; `3 y; I! P- A5 i- H
B/ I7 ]. r0 G2 l5 g9 U! @' Z0 l7 o1 D
; j6 f& ]1 o# K& Y: S( A' Y
6 w9 O' B. [) _. N: E
图2- F5 {, m8 R, z* a7 k
接下来的动作就是Ctrl+Break,断下Debuggee的OS,然后就会出现如下图3所示的界面,这时就可以开始下断点,跟踪 程式,查看程式的上下文,查看寄存器的值等等。想干嘛,随你的便J! - _6 S3 k) B/ h0 z ?# x
图3$ |% F9 V8 U8 d1 f9 D
* s& k) X7 s- ^" K
9 i9 ] m1 }: V. `3 _3.Let’s Begin Fighting It
7 w/ ~: Y b6 v: H" `9 f
. y9 | V/ B; |; H# ?, R空谈误国,实战兴邦。罗嗦了这么多废话,现在要开始行动了。首先我们要先输入!amli debugger 启动amli调试器,第一次可能会失败,报下述错误:AMLI_DBGERR: failed to get debugger flag address。这个错误的原因可能是:
" x. C4 h% i8 K* {& j( W! c1.Checked Acpi.sys和Acpi.pdb文件和debuggee版本不符导致的。
1 \% c o& M' G2.WinDbg没有load Acpi符号文件,只要.reload即可。下面我将给出几个小的sample,演示如何debug asl code。
1 g& r i3 i# j+ X' \9 R$ ]6 R8 H% y; Y1 ^! P# l! t+ x
a)Dump Acpi namespace device objects+ C, Y. U/ E7 Z6 V: E, F/ X
' [4 n) u+ H" b/ d输入!amli dns /s \_sb.pci0.sbrg.ec 在我的调试环境下将会出现下述内如图4所示,\_sb.pci0.sbrg.ec这是Acpi device8 y( O5 L7 w$ Q& v2 w
Object 路径,每个bios的实现可能不同,这里是我的debuggee下EC这个device的路径。嘿嘿…怎么样,EC的秘密一览无余了吧。
( E9 @* u1 |! W0 C9 N9 w# n4 \! E1 s* x6 C/ D# e
1 t. F) A2 F6 l; F0 P. x4 y, V
; f: a1 O( p y: L! a! K
图4
6 @! U3 |7 j7 U3 T/ w/ F- pb)Set breakpoints in Acpi method
! t3 m( `; h+ r& e E( B! G2 n3 }% S
输入!amli debugger ègo,然后一旦aml被解释WinDbg就会被断下,这时我们再输入!amli bp\_sb.pci0.sbrg.ec.bat1. _staègo这时我们就在battery _sta这个method下了个断点,一旦该method被call,那么我们就会hit the breakpoint。那么该方法什么时候会被call呢?Acpi spec有如下描述:3 x! x# V! h: R6 A4 U: n, s
* {5 Q% h! I+ ~* ^) \0 U
* \+ J6 I/ {' u& O
3 \- @) s! e5 r' s
图5
8 e3 e. u, _+ [/ U; s, c也就是说一旦有device插拔动作该method就会被call,那么我们拔掉battery试试看会怎么样呢?下图6给出了答案,我们的断点被hit了。- A1 v0 @ a* L
/ b& ]6 A- X1 y' K
F1 P5 \1 M U) ]3 d' k$ Z% H }0 L8 j* h1 c" C C
图6
! V5 r& b1 _# q: w0 `4 l被断下以后我们可以在WinDbg查看各种信息,例如使用r检查上下文信息,ln列出breakpoints最近的method,p单步查看各个参数的值等等,help yourself!J. v. m2 W$ v' b h) a
8 x+ J% R* ^3 X" Y: L0 |8 {
c)Tracking processes of S3/4/5
- D" g3 x$ P8 h2 h0 m- S( A7 q8 e/ _0 D5 q- b
我一直不清楚当os下S3/4/5的时候流程是怎样?会执行哪些 asl code而且我们又时不时的会碰到与之相关的问题,烦不胜烦。怎么办呢?Let’s scratch it。输入!amli debugger ègo,下来输入 set verboseon èset traceonègo,然后我们选择让debuggee 关机进入S5,WinDbg将会出现下图7类似的输出。这些就是下S5 Acpi asl code的完整process。我们发现OS先会去获得一些AC,BAT,LID等设备的信息,然后会call\_PTS(0x5) method 0x5就表示S5。S5追过了,S3/S4那就如法炮制。
3 k4 h9 d9 Q7 m4 L {, F# T$ m; ?1 F* M
4 x! t" a0 n5 c5 p6 O3 M* i8 Z8 M2 B$ C$ G
9 w+ x; T9 B% o0 x t/ O' A
: o% d1 y& m) c B: w. L9 i7 @& H1 \
图70 f; O0 [2 v6 Z+ y; f: ]0 b
REFF:- }/ X( `+ `; m
; `# B7 b: F# P/ g
1.如何跟踪ACPI代码
: y1 c# ~% @6 q* Z6 ^' @* u! k/ D$ F% h2.如何使用WinDbg跟踪调试ASL/ACPI
7 |6 x: b! }; d2 N+ e3 v% ? T+ o6 g1 H3 I+ j! N% G
Peter |