|
Tracking ACPI/ASL Using WinDbg 8 s' v+ k2 b9 Q! B7 v; |
' v1 M0 z9 Q& @! {
1. Preface
' H/ D( Y$ x+ P% D2 H( @
2 K* }, g; P. j; r$ CACPI是BIOS和OS之间沟通的主要手段,所以有些系统相关的问题,都跟ACPI asl code有很大的关系,如果能够直Debug ACPI asl code那将会对解决这类问题提供很好的帮助。这篇文章的目的就是讲解如何使用WinDbg实现ACPI/ASL code源码级别的调试。
7 R; F' X K) S8 Z0 T. S6 O6 ~( F1 w. C
2. Configuration of Debugger & Debuggee1 I/ w0 O3 K$ V: X; `0 ]3 ~
+ S2 K. x6 i" S0 k+ VDebug ACPI 最好是双机调试,一台主机Debugger和一台目标机器Debuggee。WinDbg支援COM,1394,USB2.0三种不同的连接方式。它们的配置方法都大同小异,我使用的1394,所以我将介绍1394的配置方式。
: Q2 d3 e% k" d, ua)设置Debuggee为调试模式6 u) Q0 r& a/ y w
启动Debuggee进入OS,点击开始菜单选择运行,然后输入msconfig然后选择BOOT.INIèAdvanced Optionsè/DEBUG剩下的具体方式如下图1所示,其中/CHANEL选择可以随便指定,但是要和Debugger端设置的要一致。
, w: F$ u) C7 o; _! ?7 O% I% k4 V5 |; V( A
3 I9 D& T% G; K图1
$ {2 m" k/ y% Q0 Z) g8 h
! ?; T; a# X1 r3 L. Vb)安装设置WinDbg9 J- Q: d; n, A% S
5 n: Y$ P+ _. ^* b( X# \+ aWinDbg是微软提供的免费的Debug工具(微软还是不错的J),它非常强大,可以调试各种程序包括ACPI,Driver,AP而且它甚至可以用于Windows OS Kernel Debug,据说微软自己也使用该程式辅助开发他们的OS, WinDbg在微软网站上有免费下载。如果你在别的机器上已经安装好了WinDbg,那么可以直接copy过来就能使用了。
, o( M3 V6 k; ^7 j# z# K! ?! `+ u& x4 W( _) Q$ _. p* g
c)安装Symbol File5 a; N/ w) w% r. z% T; m8 \
/ E8 a6 M: i, ~7 E- z* E( w什么是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文件可以在微软网站上免费下载。
& A5 l- S8 Y6 x I7 N' @) p
+ g: s$ L) [' h, H4 {6 Ud)安装Checked Acpi.sys) A! w9 [, t: t/ a2 W
/ E9 ~/ V3 T: O; L+ a' aBIOS中的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。2 M7 t* M- Y U, ]2 y
( \6 E: w/ D8 L% D% C6 x
e)Start Kernel Debug $ m; a7 t4 {5 R {% O
打开WinDbg选择FileèKernel Debugè1394(channel 1)èOK5 W \; |1 e/ K# I4 z' y( L
如下图2所示:8 Q) @' O# T3 V( G6 P
5 L# D1 x1 r( W: J6 r9 s q& P1 { n6 _. b4 J5 T" P4 C9 N
: d9 @* i' C9 u' }! @
; R) S- k- a) Z6 F; e& P; F
图2
7 N; |$ P$ x2 s! Y+ Q接下来的动作就是Ctrl+Break,断下Debuggee的OS,然后就会出现如下图3所示的界面,这时就可以开始下断点,跟踪 程式,查看程式的上下文,查看寄存器的值等等。想干嘛,随你的便J! : j+ }. ~( v* U
图3
?# ^# q) T% @( U" f4 v
6 W6 P1 w" E7 J
! k0 e/ x% E: {: [: o, l( R3.Let’s Begin Fighting It
8 @; j: C, l( y
5 \3 `# j5 t% T/ d9 g/ [. i空谈误国,实战兴邦。罗嗦了这么多废话,现在要开始行动了。首先我们要先输入!amli debugger 启动amli调试器,第一次可能会失败,报下述错误:AMLI_DBGERR: failed to get debugger flag address。这个错误的原因可能是:( u6 N4 i# I% v
1.Checked Acpi.sys和Acpi.pdb文件和debuggee版本不符导致的。
6 X0 V3 P- i1 |, q: Z- s$ b. V j2.WinDbg没有load Acpi符号文件,只要.reload即可。下面我将给出几个小的sample,演示如何debug asl code。
) N" W, q# ?1 l) N2 L% U! N6 D' t% m9 v0 h2 P0 s
a)Dump Acpi namespace device objects: v [/ W& N- x
; B" v& k& Z3 N0 \7 d* B输入!amli dns /s \_sb.pci0.sbrg.ec 在我的调试环境下将会出现下述内如图4所示,\_sb.pci0.sbrg.ec这是Acpi device
& K4 }5 O2 f# W3 z) `+ QObject 路径,每个bios的实现可能不同,这里是我的debuggee下EC这个device的路径。嘿嘿…怎么样,EC的秘密一览无余了吧。. w: o' A d& J, y" S2 C/ J
& [" }5 V- _. A( m1 O4 G
3 m. f7 M0 v2 _' ~% B
* }$ w& n2 {/ U: w6 S- Z
图4+ \% u3 q5 p# i) D" k. C
b)Set breakpoints in Acpi method
$ k8 O: Q$ @8 \- y" R3 I. b4 [: ^ `6 |+ _, N, G
输入!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有如下描述:
& g$ S9 C' s" b2 U$ A3 t& @3 p0 ?
+ {, k" `; o) Y* n) f$ F: Y( D3 G! E* O
5 n8 i9 _- W. C# ~; ?# ?
图5
3 y& E+ i6 q7 g. O/ J+ L也就是说一旦有device插拔动作该method就会被call,那么我们拔掉battery试试看会怎么样呢?下图6给出了答案,我们的断点被hit了。
9 o2 e, X2 }: H- G0 G6 z& F& b4 Q) a
1 L9 h% I; s! f* W: K K
- x8 F2 N I: w9 \. y图6
) ?+ a# J. X9 y) A% S; c被断下以后我们可以在WinDbg查看各种信息,例如使用r检查上下文信息,ln列出breakpoints最近的method,p单步查看各个参数的值等等,help yourself!J
" \+ N8 I# d( T |, l2 ^0 Y
' z( V. P9 Y% Z8 G& |- D- ? uc)Tracking processes of S3/4/5+ @& F) `3 T* Y- D
; e* ^0 \8 k& e& j6 }1 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那就如法炮制。
; o% r! m5 Z7 P! j- l6 c" H/ O3 a$ w7 r7 m6 A1 s
! O8 s& P& [3 N, Z
5 k6 R/ S& Y) P
# r$ S6 A3 i9 a0 m9 a$ \
图7
2 R. g" g2 u: f0 c' d8 }5 W" c3 @* IREFF:, I' W U+ `$ z( o" p) ~" l
, `/ `7 B) j- z1 z" f& C, a) ?9 d5 v
1.如何跟踪ACPI代码% s* Q- | T2 d4 z, U
2.如何使用WinDbg跟踪调试ASL/ACPI
' }- t) g' d& \0 u/ ` & a! I& D& r0 ?$ y& U+ y7 T2 J4 O, v2 c
Peter |