当前位置: 代码迷 >> 综合 >> CRASH ANALYSIS of PPC440+OSE PLATFORM
  详细解决方案

CRASH ANALYSIS of PPC440+OSE PLATFORM

热度:25   发布时间:2024-01-09 16:40:06.0

 

 

CRASH ANALYSIS of PPC440OSE PLATFORM

Sailor_forever  sailing_9806@163.com 转载请注明

 

【摘要】本文分析了PPC440OSE平台下系统Crash的相关底层技术。首先介绍了PPC440的寄存器及系统crash时的基本处理流程,接着分析了PPC ABI规范,确定了函数调用时的参数传递规则和栈结构,这些都为crash时的寄存器组和栈分析奠定了基础。最后以DATA TLB MISS异常为例,详细介绍了如何根据DUMP文件分析系统死机原因。

 

【关键字】PPC440OSECRASHDATA TLB MISS

 

1          寄存器

1.1      寄存器按处理器模式分类

用户权限可以访问的寄存器

 

只有特权模式可以访问的寄存器

 

1.2      寄存器按功能类型分类

1.2.1        分支跳转

CR User CR 66

CTR User SPR 66

LR User SPR 65

 

CTRCount Register

作为loop循环计数,自动递减,一些条件转移指令可以利用其进行分支转移

 

CRCondition Register

条件寄存器,算术运算指令后会自动更新改寄存器,条件分支转移指令使用

 

LRLink Register

函数调用时,程序的返回地址,即下一条待执行的指令的地址

 

1.2.2        Cache 控制

DNV0–DNV3 Supervisor SPR 94

DTV0–DTV3 Supervisor SPR 94

DVLIM Supervisor SPR 96

INV0–INV3 Supervisor SPR 94

ITV0–ITV3 Supervisor SPR 94

IVLIM Supervisor SPR 96

 

1.2.3        Cache Debug

DCDBTRH, DCDBTRL Supervisor, read-only SPR 121

ICDBDR, ICDBTRH, ICDBTRL Supervisor, read-only SPR 106

 

1.2.4        Debug

DAC1–DAC2 Supervisor SPR 242

DBCR0–DBCR2 Supervisor SPR 235

DBDR Supervisor SPR 243

DBSR Supervisor SPR 240

DVC1–DVC2 Supervisor SPR 242

IAC1–IAC4 Supervisor SPR 241

 

Device Control Implemented outside core Supervisor DCR 52

 

1.2.5        Integer Processing

GPR0–GPR31 User GPR 69

XER User SPR 69

GPR0–GPR31:通用寄存器组,R0――R31

 

1.2.6        Interrupt Processing

CSRR0–CSRR1 Supervisor SPR

DEAR Supervisor SPR

ESR Supervisor SPR

IVOR0–IVOR15 Supervisor SPR

IVPR Supervisor SPR

MCSR Supervisor SPR

MCSRR0-MCSRR1 Supervisor SPR

SRR0–SRR1 Supervisor SPR

 

CSRR0–CSRR1Critical Save/Restore Register

CSRR0:用于产生critical中断时保存返回的PC指针

CSRR1:用于产生critical中断时保存当前的MSR

 

DEAR Data Exception Addr Register

Loadstorecache管理等指令读取内存发生Alignment, Data TLB Miss, or Data Storage等错误时,将错误的地址存于DEAR

 

ESRException Syndrome Register

当触发某种异常或者中断时,可能需要查看具体是哪种子中断,相当于中断的偏移量

 

IVOR0–IVOR15Interrupt Vector Offset Registers

中断矢量偏移寄存器,CPU级共16个中断,每个中断向量的入口地址的低位由此寄存器决定

 

IVPRInterrupt Vector Prefix Register

中断矢量基址寄存器,中断向量地址的高16位统一由此决定

 

SRR0–SRR1Save and Restore Register

引起异常的指令地址或者中断返回的下一条指令地址

 

1.2.7        Processor Control

CCR0 Supervisor SPR

CCR1 Supervisor SPR

MSR Supervisor MSR

PIR, PVR Supervisor, read-only SPR

RSTCFG Supervisor, read-only SPR

SPRG0–SPRG3 Supervisor SPR

SPRG4–SPRG7 User, read-only; Supervisor SPR

USPRG0 User SPR

 

MSRMachine State Register

机器状态寄存器,部分中断使能由此控制,处理器模式由此控制

 

1.2.8        Storage Control

MMUCR Supervisor SPR

PID Supervisor SPR

 

MMUCR Memory Management Unit Control Register

 

1.2.9        Timer

DEC Supervisor SPR

DECAR Supervisor, write-only SPR

TBL, TBU User read, Supervisor write SPR

TCR Supervisor SPR

TSR Supervisor SPR

 

2          中断处理

2.1      中断概念

指令执行、收到外部信号、内部定时器、调试事件及错误事件都可能导致异常,当相应异常使能时,CPU会暂停当前的工作进入异常处理,此即为中断处理。

 

2.2      中断类型划分标准

除了Machine Check中断外,所有中断可以按照两种标准进行划分:

Asynchronous or synchronous

Critical or non-critical

 

Asynchronous中断:和当前指令的执行无关,是随机的,如外部中断

Synchronous:是指由于指令本身的执行导致的异常

 

Critical:必须立即处理,即使当前仍在处理某些类型的中断时也需要停下来,处理该重要的中断

non-critical:相比较而言不太重要的中断,可以被Critical事件中断

 

2.3      中断处理相关的寄存器

Save/Restore Registers (SRR0–SRR1)

Critical Save/Restore Registers (CSRR0–CSRR1)

Data Exception Address Register (DEAR)

Interrupt Vector Offset Registers

(IVOR0–IVOR15)

Interrupt Vector Prefix Register (IVPR)

Exception Syndrome Register (ESR)

Machine State Register (MSR)

具体意义见相关寄存器说明

 

2.4      中断类型

内核使用IVPRIVORn寄存器保存中断向量。每个中断向量的入口地址是IVPR+IVORnIVPR提供中断向量的基址,IVORn提供中断向量的偏移。IVORn与异常的对应关系如下:

IVOR0 Critical Input

IVOR1 Machine Check

IVOR2 Data Storage

用户模式下访问内核模式才能访问的内存空间,或者数据访问的字节序与定义的字节序不一致引发的异常

IVOR3 Instruction Storage

在用户模式访问内核模式下才能访问的内存空间,以及因为指令预取部件访问的字节序与定义的字节序不一致时引发此异常。

IVOR4 External Input

IVOR5 Alignment

 

IVOR6 Program

执行非法指令,在用户模式下执行内核模式才能执行的指令或者tw指令条件满足时,产生此异常。

IVOR7 FP Unavailable

IVOR8 System Call

执行sc指令产生此异常

IVOR9 AP Unavailable

IVOR10 Decrementer

DEC寄存器产生的定时器异常, PowerPC利用此异常实现时钟中断

IVOR11 Fixed Interval Timer

IVOR12 Watchdog Timer Watchdog

IVOR13 Data TLB Miss Error

当处理器取指时,如果访问指令的地址没有在TLB中命中时产生此异常

IVOR14 Instruction TLB Miss Error

当处理器取指时,如果访问指令的地址没有在TLB中命中时产生此异常

IVOR15 Debug

 

内核初始化的时候,会把所有需要初始化的IVOR赋上恰当的值。当有对应异常发生时,直接跳转到IVPR+IVORn所指向的地址即可。

 

2.5      中断处理的基本流程

如果当前异常使能且优先级更高,则中断处理的流程如下:

1、保存被中断程序的返回地址或者错误指令的地址到SRR0 (for non-critical class interrupts) or CSRR0 (for critical class interrupts) or MCSRR0 (for Machine Check interrupts)

根据异常类型更新ESR或者MCSR,即可获得更详细的中断类型

 

2、保存MSR寄存器到SRR1 (for non-critical class interrupts) or CSRR1 (for critical class interrupts) or MCSRR1 (for Machine Check interrupts),如果是地址异常还会保存错误地址到DEAR寄存器中

 

3、更新MSR,原则如下:

清除MSR[WE,EE,PR,FP,FE0,DWE,FE1,IS,DS]

critical class interrupts 清除MSR[CE,DE] non-critical class不清除,因此non-critical class interrupts可以被critical class interrupts中断

Machine Check interrupts 清除MSR[ME],其他中断不清除

 

4、清除PRISDS位。此时,处理器运行在内核模式

5、根据IVPRIVOR4寄存器获得中断向量,进行中断程序执行

6、中断程序执行结束后,使用rfi/rfci/rfmci指令返回。rfi/rfci/rfmci指令从SRR1/CSRR1/M CSRR1寄存器恢复MSR寄存器,从SRR0/CSRR00/MCSRR0寄存器中获得中断的返回地址,注意这两步其实是一个原子操作

 

3          PowerPC中的ABI规范

ABIEABIExtend ABI)通常是处理器体系结构的一部分,它与平台是紧密相连的。可以把ABI理解为一套规则,这套规则一般包括定义了以下内容:

1、如何使用机器的寄存器。比如用那个通用寄存器来作stack pointerframe pointer

2、堆栈的结构。

3、参数传递规则。

 

特定于那个平台的编译器和链接器实现都要遵循这些约定。

 

3.1      寄存器的使用规则

GPR0:随意使用,无需保存

GPR1:该寄存器保存堆栈的栈顶指针,也就是SP指针。

GPR2:专用

GPR3GPR4:使用这两个寄存器保存程序的返回值。

GPR3GPR10:用于传递函数参数。当参数多于8个时,使用存储器的栈传送。

GPR11GPR12 随意使用,无需保存

GPR13:专用,该寄存器用于保存sdata段的基地址指针。

GPR14GPR31:程序可以自由使用这几个寄存器。

 

共分为三类

Volatile:随意使用,函数调用或者中断时不用保存

Nonvolatile:非易失性的,使用前需要保存,用后恢复

Dedicated:专用的,如R1作为SP,不能用于其他用途,因为中断可能随时来临

 

3.2      堆栈的结构

PowerPC架构没有专门的pushpop指令来实现堆栈结构,因此需要有一套规范来支持参数传递、Nonvolatile寄存器的保存以及局部变量等。将这些数据以统一的格式存放在栈中。

 

3.2.1        栈的增减规则

SP总是以双字对齐的方式指向当前stack frame的底部,新的SP递减增长,。

 

 

3.2.2        栈的结构

进行函数调用时,堆栈将向下增长,并按照特定的格式保存现场,以防止中断后无法返回到调用处。

 

                                         

 

Back Chain:当前栈顶指针寄存器SP保存上一个栈桢的Back Chain的地址。当函数返回时,SP指回上一个栈桢。

LR Save Word:保存LR寄存器的值,用于函数返回,即调用函数处的下一条指令地址。

Parameter Save Area:用于存放函数参数。当参数多于R3-R10 8个时才用此区域。

Local Variable Area:用于存放临时变量。首先选择GPR0/GPR11/ GPR12保存临时变量,只有当寄存器不够用时才用此区域。

CR Save Area:若函数可能更改CR,则保存CR寄存器。

32-bit General Register Save Area:保存函数用到的32位寄存器。若使用了GPR14- GPR31之间的寄存器,则需要将之上至GPR31的所有寄存器入栈保存,如使用了GPR16,则应保存GPR16- GPR31

 

注意,根据具体的函数不一样,栈桢的内容是不一样的,最小的栈桢只有Back ChainLR Save Word,共8字节,栈始终对齐在8字节边界,否则填充补齐。

 

Back ChainLR Save Word紧紧相邻,且Back Chain是递减的,这些特征便于定位哪个是函数调用的边界。

 

3.3      函数调用示例

以下使用一VxWorks的入口函数简单分析下,中间插入部分汇编。

void usrInit (int startType)

{

        stwu        r1,-0x20(r1);    /* 保存原先sp,同时更新sp */

        mflr        r0;                 /* LR 获取 */

        stw         r31, 0x1C(r1);   /* 非易失性reg保存,这只保存r31 */

        stw         r0,  0x24(r1);   /* LR存储在上个堆栈sp+4 */

        mr          r31, r1            /* r31为当前sp */

        stw         r3,  0x8(r31)    /* 局部变量,也就是startType */

       

    sysStart (startType);            

        lwz         r3,  0x8(r31)

        crclr       0x6

        bl          0x1E11F8BC       /* 函数跳转 */

         

    cacheLibInit (USER_I_CACHE_MODE, USER_D_CACHE_MODE);

        li          r3, 01

        li          r4, 01

        bl          0x1E80EE0

 

    excVecInit ();                    

    sysHwInit ();                    

    usrCacheEnable ();                

    usrKernelInit ();                

}

        lwz         r11, 0x0(r1)      /* SP恢复 */

        lwz         r0,  0x4(r1)

        mtlr        r0                  /* LR 恢复 */

        lwz         r31, -0x4(r11)   /* R31恢复 */

        mr          r1,  r11

        blr                             /* usrInit函数返回 */

 

 

4          Data TLB Miss 分析

4.1      Dump文件分析

4.1.1        错误代码解析

[POST MORTEM DUMP]

user called :  0

error code  :  0x00000000

extra       :  0x00000000

curr_proc   :  0x00010179

 

[ERROR HANDLER PARAMETERS]

user called :  0 (Kernel)

error code  :  0x91000113

extra       :  0x002a3e58

curr_proc   :  0xe2a3835a

 

 

ERROR NUMBER 0x91000113 WITH EXTRA DATA 0x002A3E58 OCCURRED IN

PROCESS  irqProc

TYPE PRI-15

BLOCK   CXC1727187%1_R3N02

 

ERROR SPECIFICATION

An unexpected exception occurred.

The exception offset is supplied in the subcode field.

The extra parameter contains a pointer to a register

dump, described in cpu.h

This error is fatal.

The exception vector = 0x1100, Data TLB Miss.

 

错误源user called0内核发现的错误

错误代码:0x91000113113的详细解释为Data TLB Miss,异常入口0x1100

错误附加值:0x002A3E58,指向dump的寄存器组

错误进程:0x00010179,代表优先级为15的进程irqProc

程序版本:可加载程序CXC1727187%1_R3N02

 

4.1.2        Dump寄存器分析

[REGISTERS FOR PROCESS 0x10179 irqProc]

PC  = 00655304  SP  = 03C87E10  MSR = 00029030  LR  = 03CFD778

 

R0  = 00000001  R8  = 002A0000  R16 = 40220000  R24 = 42EC0000

R1  = 03C87E10  R9  = 000003D4  R17 = 40220000  R25 = 42FC4B40

R2  = 42E75C0C  R10 = 00029030  R18 = 40220000  R26 = 00000001

R3  = 03C84890  R11 = 0331FDC0  R19 = 42E40000  R27 = 00000000

R4  = 00029030  R12 = 03C84740  R20 = 42E40000  R28 = 42ED0114

R5  = 00021030  R13 = 42ED1180  R21 = 42E40000  R29 = 42ED0000

R6  = 0006CB8D  R14 = 40220000  R22 = 42E40000  R30 = 03C8B2A0

R7  = 00000000  R15 = 40220000  R23 = 42E40000  R31 = 03C87960

 

DAR = 03320194  CR  = 42500002  XER = 00000000  CTR = 0062AA64

 

[OTHER PROCESSOR REGISTERS]

PVR   = 21821820

CCR0  = 48000000     CCR1  = 00000000     CR    = 22502088    

CSRR0 = 005EB840     CSRR1 = 00000000     CTR   = 00000000    

DAC1  = 00000000     DAC2  = 00000000     DBCR0 = 00000000    

DBCR1 = 00000000     DBCR2 = 60000A00     DBDR  = 00000210    

DBSR  = 00000000     DCDBTRH= 00000000    DCDBTRL= 00040820   

DCRIPR= 00000000     DEAR  = 03FB4004     DEC   = 0018F671    

DECAR = 00000000     DNV0  = 021E1314     DNV1  = 25091031    

DNV2  = 3E38242B     DNV3  = 03003026     DTV0  = 00000000    

DTV1  = 00000000     DTV2  = 00000000     DTV3  = 00000000    

DVC1  = 88010C00     DVC2  = 40000A00     DVLIM = 00000000    

ESR   = 00000000     IAC1  = 00000000     IAC2  = 00000000    

IAC3  = 00000000     IAC4  = 00000000     ICDBDR= FFFFFFFF    

ICDBTRH= 00000000    ICDBTRL= 00000000    INV0  = 2B382F34    

INV1  = 08090025     INV2  = 182B0A0F     INV3  = 3839111D    

ITV0  = 00000000     ITV1  = 00000000     ITV2  = 00000000    

ITV3  = 00000000     IVLIM = 00000000     IVOR0 = 00000100    

IVOR1 = 00000200     IVOR2 = 00000300     IVOR3 = 00000400    

IVOR4 = 00000500     IVOR5 = 00000600     IVOR6 = 00000700    

IVOR7 = 00000800     IVOR8 = 00000C00     IVOR9 = 00000D00    

IVOR10= 00000900     IVOR11= 00000A00     IVOR12= 00000B00    

IVOR13= 00001100     IVOR14= 00001200     IVOR15= 00002000    

IVPR  = 00000000     MCSR  = 00000000     MCSRR0= 00647938    

MCSRR1= 00000000     MMUCR = 00000006     PID   = 00000000    

PIR   = 00000000     RSTCFG= 00000000     SPRG0 = 03CC0000    

SPRG1 = 00244D34     SPRG2 = 0062AA64     SPRG3 = 42500002    

SPRG4 = 00000000     SPRG5 = 00000000     SPRG6 = 00000000    

SPRG7 = 00000000     SRR0  = 0067AF9C     SRR1  = 00021030     

TBL   = ADDC399C     TBU   = 5080D45A     TCR   = 00000000    

TSR   = 00000000     USPRG0= 00000001    

 

DDR2MC_BESR   = 00000000

DDR2MC_BEARL  = 00000000

DDR2MC_BEARU  = 00000000

DDR2MC_ECCES  = 00000000

OPB2PLB_GSTAT = 00000000

OPB2PLB_GEARL = BBB5FF9D

OPB2PLB_GEARH = 0000000E

PLB2OPB_GEAR  = FFFFFFC0

PLB2OPB_GEARU = 00000000

PLB2OPB_GESR0 = 00000000

PLB2OPB_GESR1 = 00000000

EBCO0_BEAR    = 00000000

EBCO0_BESR    = 00000000

 

关键寄存器分析

PC  = 00655304 

下一条待执行的指令地址,由于流水线的因素,PC并不是当前执行的指令地址

 

SP  = 03C87E10 

异常时当前函数调用层次的堆栈指针,堆栈递减的,由SP及当前任务堆栈的栈顶即可知道调用的层次关系及相关变量、参数等

MSR = 00029030  

机器状态字

 

LR  = 03CFD778

待返回的函数中下一条指令的地址

 

IVPR  = 00000000

异常入口的计算方法IVPR  IVORx 0x1100

推算IVORx IVOR13,根据PPC440中断向量表即可知此为Data TLB Miss异常

 

DEAR  = 03FB4004

Data TLB Miss异常为数据访问异常,此时导致错误的虚拟地址将保存在DEAR中,错误地址为03FB4004Data TLB Miss异常,说明未找到虚拟地址03FB4004的映射关系,可能因为为03FB4004不存在于任何一个页表范围内,或者本任务对03FB4004地址没有访问权限。

 

SRR0  = 0067AF9C     SRR1  = 00021030

产生错误的指令地址保存在SRR0中,为0067AF9C

结合相关map表,即可知道0067AF9C所对应的文件、函数、代码行等信息。

 

 

4.1.3        内存布局分析

 

描述了各个Segments and regions的内存分布,结合PCSPLRDEARSRR0即可找到错误的代码段及数据段

 

[MEMORY MANAGER]

MEMORY LEFT: 6455296 bytes = 6,2 Mbytes

 

Segments and regions

 

SEGMENT NAME     NUMBER  OWNER ID  SEGMENT ID  MODE

SYSTEM_SEGMENT   1       65597     0           usermode

 

。。。。。。。。。

 

VECTORS          3       0x00000000-0x00004000 0x00004000

super_wp user_wp persistant copyback physical

 

PBOOT            4       0x00004000-0x000416D4 0x0003D6D4

user_wp persistant copyback physical

 

。。。。。

 

OS_CODE          6       0x00500000-0x0077DC00 0x0027DC00

super_wp user_wp persistant copyback physical

 

OS_DATA          7       0x00200000-0x003787B1 0x001787B1

user_wp public persistant copyback physical

 

OS_NOVRAM        8       0x0037C000-0x003809A9 0x000049A9

user_wp persistant copyback physical

 

INIT_MAINPOOL    9       0x00800000-0x009A4000 0x001A4000

public persistant copyback physical

 

。。。。。。。。

 

Mainpool_Frag_1  2       0x03FD4000-0x03FF4000 0x00020000

public copyback physical

 

Syspool_Frag_1   19      0x03FB4000-0x03FD4000 0x00020000

copyback physical

 

。。。。。。。。。

 

Mainpool_Frag_19 50      0x03CE0000-0x03D00000 0x00020000

public copyback physical

 

。。。。。。

 

Syspool_Frag_3   53      0x03C80000-0x03CA0000 0x00020000

copyback physical

。。。。。。。。。

 

分析:

OS_CODE          6       0x00500000-0x0077DC00 0x0027DC00

SRR0  = 0067AF9C OS_CODE的范围内,说明产生异常时正在运行内核代码

 

Syspool_Frag_3   53      0x03C80000-0x03CA0000 0x00020000

SP  = 03C87E10 Syspool_Frag_3范围内,说明irq_proc在内核态使用了Syspool_Frag_3作为栈空间

 

Syspool_Frag_1   19      0x03FB4000-0x03FD4000 0x00020000

DEAR  = 03FB4004 产生错误的地址位于此段,当有属性权限控制时,可能为非法内存访问导致TLB异常

 

4.1.4        内存池分析

[POOL INFO]

poolid       frags   totsize      used    unused   used%

0x1000c         21   4341728   4278752     62976      99   Main

0x10000          4    818336    733120     85216      90   OSE

 

Pool: Main

Pool id 0x1000c

signal sizes 8

sig_conf       31      63     127     255    1055    4095   16383   65535

sig_alloc    1161     643      40     227      38      70     108       0

stack sizes 8

stk_conf      256     512    1024    2048    4096    8192   16384   65536

stk_alloc       0       6       6      74      62      31       6       1

fragment info

fragment    baseaddr    lastaddr     size  sigsize  stksize   unused used%

0         0x03ca0000  0x03cc0000   131072    68096        0    62976    51

1         0x03ce0000  0x03d00000   131072   110656    11264     9152    93

2         0x03d00000  0x03d20000   131072    79520    36864    14688    88

3         0x03d20000  0x03d40000   131072   125728     5120      224    99

4         0x03d40000  0x03d60000   131072   127968        0     3104    97

5         0x03d60000  0x03d80000   131072   127968        0     3104    97

6         0x03d80000  0x03da0000   131072   127968        0     3104    97

7         0x03da0000  0x03dc0000   131072   127968        0     3104    97

8         0x03dc0000  0x03de0000   131072   127968        0     3104    97

9         0x03de0000  0x03e00000   131072   128416        0     2656    97

10        0x03e00000  0x03e20000   131072   116128        0    14944    88

11        0x03e20000  0x03e40000   131072   115520        0    15552    88

12        0x03e40000  0x03e60000   131072   116128        0    14944    88

13        0x03e60000  0x03e80000   131072   116128        0    14944    88

14        0x03e80000  0x03ea0000   131072   116128        0    14944    88

15        0x03ea0000  0x03ec0000   131072   115520        0    15552    88

16        0x03ec0000  0x03ee0000   131072   116128        0    14944    88

17        0x03ee0000  0x03f00000   131072   116128        0    14944    88

18        0x03f84000  0x03fa4000   131072   116128        0    14944    88

19        0x03fd4000  0x03ff4000   131072   115520        0    15552    88

20        0x00800000  0x009a3fe0  1720288   902368   807936     9984    99

 

Pool: System pool

Pool id 0x10000

signal sizes 8

sig_conf       31      63     127     255    1023    4095   16383   65535

sig_alloc    1773     624      92       1       0       1       0       0

stack sizes 8

stk_conf      256     512    1024    2048    4096    8192   16384   65536

stk_alloc       1       0       0       4       0       0       1       0

fragment info

fragment    baseaddr    lastaddr     size  sigsize  stksize   unused used%

0         0x03c80000  0x03ca0000   131072    45856        0    85216    34

1         0x03cc0000  0x03ce0000   131072   131040        0       32    99

2         0x03fb4000  0x03fd4000   131072   114656    16384       32    99

3         0x00310280  0x00377f20   425120   401984    22784      352    99

 

共两个内存池:

OSE,系统内存池

Main,应用程序内存池

 

4.1.5        死机进程irq-proc的栈分析

 

[SUPERVISOR STACK PREAMBLE FOR PROCESS 0x10179 irqProc]

 

 03C87860: 03fc0120 03c88260 03fb5ac0 03c86160   "... ...`..Z...a`"

 03C87870: 00000000 000100ed 000100e9 028e0002   "................"

。。。。。。。。。

 03C87A40: 00000000 00000000 00000000 eeeeeeee   "................"

 03C87A50: eeeeeeee eeeeeeee eeeeeeee eeeeeeee   "................"

 

[SUPERVISOR STACK FOR PROCESS 0x10179 irqProc]

 

 03C87A60: eeeeeeee eeeeeeee eeeeeeee eeeeeeee   "................"

 ........:< Skipping empty part of the stack  >

 03C87BD0: eeeeeeee eeeeeeee 03c87bf8 eeeeeeee   "..........{....."

 03C87BE0: 03c87c00 00000000 eeeeeeee 00000000   "..|............."

。。。。。。。。。。。

 03C87DE0: 00000001 03c84890 00029030 00021030   "......H....0...0"

 03C87DF0: 0006cb8d 00000000 002a0000 000003d4   ".........*......"

 03C87E00: 00029030 0331fdc0 03c84740 0064adfc   "...0.1....G@.d.."

 03C87E10: 03c87e38 00654f70 03c87e40 42fc4b40   "..~8.eOp..~@B.K@"

 03C87E20: 42fc4a00 00000000 00000005 42ed0000   "B.J.........B..."

 03C87E30: 42fc4a70 03cfd778 03c87e40 00649fa4   "B.Jp...x..~@.d.."

 03C87E40: 03cfd778 0067a890 42da1150 0002d030   "...x.g..B..P...0"

 03C87E50: eeeeeeee 42d0b440 eeeeeeee eeeeeeee   "....B..@........"

 

[MAIN STACK PREAMBLE FOR PROCESS 0x10179 irqProc]

 

 03CFD200: eeeeeeee eeeeeeee eeeeeeee eeeeeeee   "................"

 03CFD210: eeeeeeee eeeeeeee eeeeeeee eeeeeeee   "................"

 03CFD220: eeeeeeee eeeeeeee eeeeeeee eeeeeeee   "................"

。。。。。。。。

 03CFD3D0: eeeeeeee eeeeeeee eeeeeeee eeeeeeee   "................"

 03CFD3E0: eeeeeeee eeeeeeee eeeeeeee eeeeeeee   "................"

 03CFD3F0: eeeeeeee eeeeeeee eeeeeeee eeeeeeee   "................"

 

[MAIN STACK FOR PROCESS 0x10179 irqProc]

 

 03CFD400: eeeeeeee eeeeeeee eeeeeeee eeeeeeee   "................"

 ........:< Skipping empty part of the stack  >

 03CFD640: eeeeeeee eeeeeeee 03cfd678 42dd41cc   "...........xB.A."

。。。。。。。。。。。。。。。。。。

03CFD760: 42fc3490 03cfd768 03cfd788 42d0a0f8   "B.4....h....B..."

 03CFD770: 03cfd788 00000000 03cfd788 42d0b440   "............B..@"

 03CFD780: 42fc4a70 03cfd788 03cfd7d0 42d0b100   "B.Jp........B..."

 03CFD790: 00000000 00000002 03c84640 40220000   "..........F@@".."

 03CFD7A0: 40230000 40260000 40220000 000100ab   "@#..@&..@"......"

 03CFD7B0: 00000000 00000002 03c84640 42ec0000   "..........F@B..."

 03CFD7C0: 42ed00c4 42ed0000 42fc4a00 03cfd7d0   "B...B...B.J....."

 03CFD7D0: 03cfd7f0 42d097b4 03c83c40 0001007f   "....B.....<@...."

 03CFD7E0: 03c83c40 03c84860 03c83c40 03c84860   "..<@..H`..<@..H`"

 03CFD7F0: 00000000 42da1078 eeeeeeee eeeeeeee   "....B..x........"

 

每个进程有两个栈,用户模式的栈和supervisor模式的栈

irqProc的用户栈为03CFD200――03CFD7FF

supervisor 03C87860――03C87E5F

 

死机时的栈指针SP 03C87E10,在内核栈空间内,说明irqProc进程当前运行在内核态模式。由于栈是递减的,因此栈中的有效数据范围为03C87E10――03C87E5F

03C87E10: 03c87e38 00654f70 03c87e40 42fc4b40   "..~8.eOp..~@B.K@"

 03C87E20: 42fc4a00 00000000 00000005 42ed0000   "B.J.........B..."

 03C87E30: 42fc4a70 03cfd778 03c87e40 00649fa4   "B.Jp...x..~@.d.."

 03C87E40: 03cfd778 0067a890 42da1150 0002d030   "...x.g..B..P...0"

 03C87E50: eeeeeeee 42d0b440 eeeeeeee eeeeeeee   "....B..@........"

 

根据Back ChainLR Save Word紧紧相邻且Back Chain是递减的规则,以及SP八字节对其的规则,可确定几个函数调用点:

内核态:

03c87e38 00654f70

03c87e40 00649fa4

03cfd778 0067a890

 

进入内核态之前用户态的栈指针为03cfd778

因此03cfd778――03CFD7FF为用户态的有效栈空间

用户态:

03cfd788 42d0b440

03cfd7d0 42d0b100

03cfd7f0 42d097b4

00000000 42da1078

 

根据map文件及反汇编的代码文件,即可找到每一个地址所对应的指令

 

4.1.6        可加载模块分析

[LOADED PROGRAMS]

  Load module id: CXC1720828_RBLACK

  Load module path:

  Load module version: No version available, loaded from flash

  Start code: 0x00500000 size: 0x0027dc00

  Start data: 0x00200000 size: 0x00180a00

  Image checksum:  0x6521

 

。。。。。。。。。。

 

  Load module id: CXC1727187%1_R3N02

  Load module path: @(#)/vobs/tdrbs/hw/trax/build trax.ppc440 ppc440 miznick_trax

  Load module version: @(#)CXC1727187R3N02 2009-05-07 23:26:35 CST 96ec48c5-1195ba2b-6e4d

  Program handle: 4

  Entry point: 42d947a0

  Start code: 42c70000   Size: 00226fa8

  Start data: 42ea0000   Size: 001269f0

  BSS start:  42ea0000

  Image checksum: 0xa148

 

CXC1720828_RBLACK为内核的固件,运行地址为0x00500000

CXC1727187%1_R3N02TRAX程序,为可加载模块,其代码及数据空间是从系统堆中动态获取的,代码段首地址42c70000,全局数据段首地址42ea0000

 

4.1.7        内核运行轨迹分析

[KERNEL TRACE CONTENTS]

TRACE LOG FROM KERNEL

 

EVENT   TIME / PROCESS(pid) / SIGNAL : parameters, ...

 

Error   at 1686789.064 ms

kernel ecode = 0x91000113, extra = 0x002A3E58

proc:  CXC1727187_R3N02:irqProc(0x10179)

 

Swapped at 1686788.914 ms

out:  Main:capi_bg(0x10069)

in:   CXC1727187_R3N02:irqProc(0x10179)

 

Send    at 1686788.907 ms

from: CXC1726374_R5D01:PARA5(0x100F5)

to:   CXC1727187_R3N02:irqProc(0x10179)

00000000: 0100d509 00000001 00000001            "............"

 

Swapped at 1686784.048 ms

out:  Main:Cs_errorManTime_proc(0x10020)

in:   Main:capi_bg(0x10069)

 

Swapped at 1686784.007 ms

out:  Main:capi_bg(0x10069)

in:   Main:Cs_errorManTime_proc(0x10020)

。。。。。。。。。。。

 

Error   at 1686789.064 ms

kernel ecode = 0x91000113, extra = 0x002A3E58

proc:  CXC1727187_R3N02:irqProc(0x10179)

为系统死机事件,记录了错误值,错误程序的某个进程

 

Swapped at 1686788.914 ms

out:  Main:capi_bg(0x10069)

in:   CXC1727187_R3N02:irqProc(0x10179)

 

Send    at 1686788.907 ms

from: CXC1726374_R5D01:PARA5(0x100F5)

to:   CXC1727187_R3N02:irqProc(0x10179)

00000000: 0100d509 00000001 00000001            "............"

CXC1726374_R5D01:PARA5(0x100F5)to:   CXC1727187_R3N02:irqProc(0x10179)

发送消息,激活了irqProc(0x10179),进行任务切换,调度CXC1727187_R3N02:irqProc(0x10179)后,系统死机

 

4.1.8        系统堆分析

系统堆用于内核自身部分动态数据的存储,另外主要功能是用于动态加载模块的内存需求。

 

[HEAP SUMMARY FOR SEGMENTS]

 

Summary of Heap for segment 0x000200c7

Alloc from Memory manager threshold default

Annotation size 0

Endmark size 1

Wipe on free (OFF) Error on null (ON) Redundant bitmap (OFF)

 

Total size                     741888

Total requested                187461,  25% of total

Total used                     218912,  30% of total

Total used (high water-mark)   218912,  30% of total

Overhead and internal

fragmentation      31451,  17% of total requested

                     14% of total used

Total free        522976,  70% of total

Largest free      458512,  62% of total

External fragmentation     12% (100% - largest free / total free)

Private buffers        5

Shared buffers       142

Number of failed malloc calls (return 0)        0

 

Buffer Histogram

Size        # of free   # of used

16         0           0

16        30           0

32         6          66

48         0          49

80         1          17

128         0           1

208         0           0

336         0           1

544         1           6

880         0           3

1424         0           0

2304         1           0

3728         0           0

6032         0           0

9760         2           0

15792         0           2

25552         0           0

41344         1           0

66896         0           1

108240         0           1

175136         0           0

283376         0           0

458512         1           0

741888         0           0

1200400         0           0

1942288         0           0

3142688         0           0

5084976         0           0

8227664         0           0

 

Fragments:

Address 0x42f11658 size 741912

 

由上可知堆中每个内存块的使用情况,分配释放的次数

 

4.1.9        产生错误的指令分析

[FAILING INSTRUCTION]

 

006552E4: 880b0bcc 2c000000 41820090 38000001   "....,...A...8..."

006552F4: 980b0018 a13e001e 816b0b90 5529103a   ".....>...k..U).:"

00655304: 7ca9582e a1250004 a01e001c 7c090000   "|.X..%......|..."

00655314: 40820034 801f0034 81250034 7c004b78   "@..4...4.%.4|.Kx"

 

00655304是即将执行的下一条指令的地址

 

4.1.10    进程列表

[PROCESS LIST]

 

NAME            TYPE   STATE    LINE FILE      MAIN STACK BASE    MAIN STACK LIMIT     USAGE   SUPERV STACK BASE    SUPERV  STACK LIMIT     USAGE

 

"CXC1727187_R3N02"                        BLOCK  Segment-ID: 0x000200c7  Block-ID: 0x000200c8  Sigpool-ID: 0x0001000c  Stackpool-ID: 0x0001000c  User-mode

"irqProc"              PRI-15 running   863 "receive@ose.h"      0x03cfd400 0x03cfd7ff  42   0x03c87a60 0x03c87e5f  63        0       2  0x00010179

"drvProc"              PRI-15 wsig...   863 "receive@ose.h"      0x03d1b800 0x03d1bbff  24   0x03fb9a00 0x03fb9dff  32        0       5  0x000200e8 R1=03D1BBB8 RA=42D25618

 

"CXC1727187_R3N02"                        BLOCK  Segment-ID: 0x000200c7  Block-ID: 0x000200c8  Sigpool-ID: 0x0001000c  Stackpool-ID: 0x0001000c  User-mode

"CXC1727187_R3N02"使用的SegmentBlockSigpoolStackpool等信息都可以获得了

 

"irqProc"              PRI-15 running   863 "receive@ose.h"      0x03cfd400 0x03cfd7ff  42   0x03c87a60 0x03c87e5f  63        0       2  0x00010179

irqProc进程为running状态,所在行863 receive@ose.h

栈使用情况

用户栈 0x03cfd400 0x03cfd7ff  42  

内核栈 0x03c87a60 0x03c87e5f  63

 

与“死机进程irq-proc的栈分析”章节分析的结果一致

 

 

4.1.11    异常代码的函数调用分析

[CALLTRACE FOR PROCESS 0x10179 irqProc]

 

Translation of address registers:

PC  = 00655304  [10155304],CXC1720828_RBLACK     

LR  = 03cfd778 

DAR = 03320194 

 

Stacktrace :

Using stackpointer  : 03c87e10

内核态的栈得到的轨迹

Back chain word     : 03c87e38

    00654f70  [10154f70],CXC1720828_RBLACK     

 

Back chain word     : 03c87e40

    00649fa4  [10149fa4],CXC1720828_RBLACK     

 

Back chain word     : 03cfd778

    0067a890  [1017a890],CXC1720828_RBLACK     

 

用户态栈得到的轨迹

Back chain word     : 03cfd788

    42d0b440  [1009b440],CXC1727187%1_R3N02     ??:0  warning

1009b0bc g     F .text 00000324 _ZN17CInterruptManager3runEv

1009b3e0 l     F .text 0000003c _Z6senderPP6SIGNAL

1009b41c l     F .text 0000003c _Z7receivePKm

1009b458 g     F .text       00000388 _Z14intHandler_5msmmm

 

Back chain word     : 03cfd7d0

    42d0b100  [1009b100],CXC1727187%1_R3N02     ??:0  writezone

            0x1009b0bc                CInterruptManager::run()

 

Back chain word     : 03cfd7f0

    42d097b4  [100997b4],CXC1727187%1_R3N02     ??:0  yearistype

1009972c l     F .text 0000013c _Z9irqProc__v

 

Back chain word     : 00000000

    42da1078  [10131078],CXC1727187%1_R3N02    

1013107c g       .text       00000000 zzinit_OSE

 

实际运行的地址和map文件中的地址有一个对应的关系

PC  = 00655304  [10155304]

相当于一个线性偏移,在map中搜索的地址为10155304附近的段,结合反汇编代码可确定出错的语句

 

 

5          To be continued

MMU and TLB of PPC

Memory Management System under OSE and PPC440

 

  相关解决方案