AML 디버깅 예제
다음은 AML 디버깅을 시작하는 방법을 보여 주는 예제입니다.
Frozen 컴퓨터 조사
대상 컴퓨터가 고정되어 ACPI 문제일 수 있다고 의심되는 경우 먼저 !amli lc 확장을 사용하여 모든 활성 컨텍스트를 표시합니다.
kd> !amli lc
*Ctxt=ffffffff8128d000, ThID=ffffffff81277880, Flgs=----R----, pbOp=ffffffff8124206c, Obj=\_SB.PCI0.ISA0.FDC0._CRS
컨텍스트가 표시되지 않으면 오류가 ACPI와 관련이 없을 수 있습니다.
컨텍스트가 표시되면 별표로 표시된 컨텍스트를 찾습니다. 현재 컨텍스트(현재 인터프리터가 실행 중인 컨텍스트 )입니다.
이 예제에서 대상 컴퓨터는 32비트 프로세서에서 Windows를 실행하고 있습니다. 따라서 모든 주소는 64비트로 캐스팅되어 높은 32비트에서 무상 FFFFFFFF를 생성합니다. 약어 pbOp 은 명령 포인터("이진 작업 코드에 대한 포인터")를 나타냅니다. Obj 필드는 ACPI 테이블에 표시되는 메서드의 전체 경로와 이름을 제공합니다. 플래그에 대한 설명은 !amli lc를 참조하세요.
!amli u 명령을 사용하여 다음과 같이 _CRS 메서드를 디스어셈블할 수 있습니다.
kd> !amli u \_SB.PCI0.ISA0.FDC0._CRS
ffffffff80e4a535 : CreateDWordFieldCRES, 0x76, RAMT)
ffffffff80e4a540 : CreateDWordField(CRES, 0x82, PCIT)
ffffffff80e4a54b : Add(MLEN(), 0x100000, RAMT)
ffffffff80e4a559 : Subtract(0xffe00000, RAMT, PCIT)
ffffffff80e4a567 : Return(CRES)
AMLI 디버거에 침입
!amli 디버거 명령을 사용하면 다음에 AML 코드가 실행될 때 AML 인터프리터가 AMLI 디버거에 침입합니다.
AMLI 디버거 프롬프트가 나타나면 AMLI 디버거 명령을 사용할 수 있습니다. " !amli "를 접두사로 지정하지 않고 !amli 확장 명령을 사용할 수도 있습니다.
kd> !amli debugger
kd> g
AMLI(? for help)-> find _crs
\_SB.LNKA._CRS
\_SB.LNKB._CRS
\_SB.LNKC._CRS
\_SB.LNKD._CRS
\_SB.PCI0._CRS
\_SB.PCI0.LPC.NCP._CRS
\_SB.PCI0.LPC.PIC._CRS
\_SB.PCI0.LPC.TIME._CRS
\_SB.PCI0.LPC.IDMA._CRS
\_SB.PCI0.LPC.RTC._CRS
\_SB.PCI0.LPC.SPKR._CRS
\_SB.PCI0.LPC.FHUB._CRS
\_SB.PCI0.SBD1._CRS
\_SB.PCI0.SBD2._CRS
\_SB.MBRD._CRS
AMLI(? for help)-> u \_SB.PCI0._CRS
ffffffff80e4a535 : CreateDWordFieldCRES, 0x76, RAMT)
ffffffff80e4a540 : CreateDWordField(CRES, 0x82, PCIT)
ffffffff80e4a54b : Add(MLEN(), 0x100000, RAMT)
ffffffff80e4a559 : Subtract(0xffe00000, RAMT, PCIT)
ffffffff80e4a567 : Return(CRES)
중단점 사용
다음 예제에서는 메서드 _BST 실행되기 전에 AMLI 디버거에 침입합니다.
_BST 개체를 찾은 경우에도 실제로 메서드인지 확인해야 합니다. !amli dns 확장을 사용하여 이 작업을 수행할 수 있습니다.
kd> !amli dns /s \_sb.pci0.isa.bat1._bst
ACPI Name Space: \_SB.PCI0.ISA.BAT1._BST (c29c2044)
Method(_BST:Flags=0x0,CodeBuff=c29c20a5,Len=103)
이제 !amli bp 명령을 사용하여 중단점을 배치할 수 있습니다.
kd> !amli bp \_sb.pci0.isa.bat1._bst
메서드 내에 중단점을 배치할 수도 있습니다. !amli u 명령을 사용하여 _BST 디스어셈블한 다음, 해당 단계 중 하나에 중단점을 배치할 수 있습니다.
kd> !amli u _sb.pci0.isa.bat1._bst
ffffffffc29c20a5: Acquire(\_SB_.PCI0.ISA_.EC0_.MUT1, 0xffff)
ffffffffc29c20c0: Store("CMBatt - _BST.BAT1", Debug)
ffffffffc29c20d7: \_SB_.PCI0.ISA_.EC0_.CPOL()
ffffffffc29c20ee: Release(\_SB_.PCI0.ISA_.EC0_.MUT1)
ffffffffc29c2107: Return(PBST)
kd> !amli bp c29c20ee
트리거된 중단점에 응답
다음 예제에서는 _WAK 메서드가 실행되고 중단점이 발생합니다.
Running \_WAK method
Hit Breakpoint 0.
!amli ln 확장을 사용하여 현재 프로그램 카운터에 가장 가까운 메서드를 확인합니다. 다음 예제에서는 32비트 형식의 주소를 보여 줍니다.
kd> !amli ln
c29accf5: \_WAK
!amli lc 확장은 모든 활성 컨텍스트를 표시합니다.
kd> !amli lc
Ctxt=c18b6000, ThID=00000000, Flgs=A-QC-W----, pbOp=c29bf8fe, Obj=\_SB.PCI0.ISA.EC0._Q09
*Ctxt=c18b4000, ThID=c15a6618, Flgs=----R-----, pbOp=c29accf5, Obj=\_WAK
활성 컨텍스트가 _Q09 및 _WAK 메서드와 연결되어 있음을 보여 줍니다. 현재 컨텍스트가 _WAK.
이제 !amli r 명령을 사용하여 현재 컨텍스트에 대한 자세한 내용을 표시할 수 있습니다. 여기에서 유용한 스레드 및 스택 정보와 _WAK 및 로컬 데이터 개체에 전달된 인수를 볼 수 있습니다.
kd> !amli r
Context=c18b4000*, Queue=00000000, ResList=00000000
ThreadID=c15a6618, Flags=00000010
StackTop=c18b5eec, UsedStackSize=276 bytes, FreeStackSize=7636 bytes
LocalHeap=c18b40c0, CurrentHeap=c18b40c0, UsedHeapSize=88 bytes
Object=\_WAK, Scope=\_WAK, ObjectOwner=c18b4108, SyncLevel=0
AsyncCallBack=ff06b5d0, CallBackData=0, CallBackContext=c99efddc
MethodObject=\_WAK
c18b40e4: Arg0=Integer(:Value=0x00000001[1])
c18b5f3c: Local0=Unknown()
c18b5f54: Local1=Unknown()
c18b5f6c: Local2=Unknown()
c18b5f84: Local3=Unknown()
c18b5f9c: Local4=Unknown()
c18b5fb4: Local5=Unknown()
c18b5fcc: Local6=Unknown()
c18b5fe4: Local7=Unknown()
c18b4040: RetObj=Unknown()
AML 코드 추적, 단계별 실행 및 실행
코드를 추적하려는 경우 다음과 같이 !amli 집합 확장을 사용하여 전체 추적 정보를 켤 수 있습니다.
kd> !amli set spewon verboseon traceon
이제 코드가 한 줄씩 실행되는 것을 보면서 AML 코드를 단계별로 실행할 수 있습니다. p 명령은 모든 함수 호출에 대해 단계를 수행합니다. t 명령은 함수 호출을 단계별로 실행합니다.
AMLI(? for help)-> p
c29bfcb7: Store(\_SB_.PCI0.ISA_.ACAD.CHAC(SEL0=0x10e1)
c29c17b1: {
c29c17b1: | Store(LGreater(And(Arg0=0x10e1,0xf0,)=0xe0,0x80)=0xffffffff,Local0)=0xffffffff
AMLI(? for help)-> p
c29c17bb: | If(LNot(LEqual(Local0=0xffffffff,ACP_=0xffffffff)=0xffffffff)=0x0)
c29c17ce: | {
c29c17ce: | | Return(Zero)
c29c17d0: | }
c29c17d0: },Local1)=0x0
AMLI(? for help)-> t
c29bfcd4: Store(\_SB_.PCI0.ISA_.BAT1.CHBP(SEL0=0x10e1)
c29c293d: {
c29c293d: | Store("CMBatt - CHBP.BAT1",Debug)String(:Str="CMBatt - CHBP.BAT1")="CMBatt - CHBP.BAT1"
선택하는 경우 AMLI 디버거 내에서 메서드를 실행할 수도 있습니다. 예를 들어 제어 메서드 _STA 실행하여 LNKA 디바이스의 상태 평가할 수 있습니다.
AMLI(? for help)-> run \_sb.lnka._sta
PCI OpRegion Access on region c29b2268 device c29b2120
\_SB.LNKA._STA completed successfully with object data:
Integer(:Value=0x0000000b[11])