IMX53外部中止

时间:2017-03-29 17:35:53

标签: linux-kernel arm abort trust-zone

我在IMX53 Sabre平板电脑上启动Android。串口上看到的最后几行是android启动时通常如下:

warning: `rild' uses 32-bit capabilities (legacy support in use)
pmem: request for physical address of pmem region from process 2262.
request_suspend_state: on (3->0) at 12032459753 (2000-01-03      
01:08:28.336600001 U
TC)
Unhandled fault: external abort on non-linefetch (0x1018) at 0x40a85054
Unhandled fault: external abort on non-linefetch (0x1018) at 0x40a85054

注意,这些外部中止不会停止启动过程并且Android正常启动。现在我想使用这些外部中止来测试我的监视器中止处理程序代码。我希望能够捕获外部中止进行监控。

在安全监视器的初始化中,我执行以下操作:

mrc p15, 0, r4, c1, c1, 0
bic r4, #0x66                      @ clear AW, IRQ, FIQ
orr r4, #0x19                      @ set FW, EA, NS
//orr r4, #0x01                     @ previously, just set NS
mcr p15, 0, r4, c1, c1, 0

我的监视器向量表如下所示:

.global tz_monitor
.align 5
tz_monitor:
@ Monitor
   b    _monitor_reset      @ Reset
   b    _monitor_undef      @ Undef
   b    smc_handler         @ SMC
   b    _monitor_prefetch   @ Prefetch
   b    _monitor_da         @ Data abort
   nop                      @ RESERVED
   b    _monitor_irq        @IRQ
   b    _monitor_fiq        @FIQ

示例异常处理函数只打印一个语句,如下所示: 在汇编中:

.global _monitor_prefetch
_monitor_prefetch:
    push {lr}
    bl monitor_prefetch
    pop {lr}
    movs pc, lr

在C:

void monitor_prefetch(void) {
    printf("In Monitor's Prefetch Handler\n");    
}

我在安全监视器的初始化中添加了这个向量表,如下所示:

ldr r0, =tz_monitor       @ Get address of Monitors vector table
mcr p15, 0, r0, c12, c0, 1 @ Write Monitor Vector Address Register

这些修改有变化,即外部中止点的内核崩溃。但我没有在监视器处理程序中获取print语句。在启动Android时,我现在在串口上获得以下输出:

warning: `rild' uses 32-bit capabilities (legacy support in use)
pmem: request for physical address of pmem region from process 2262. 
request_suspend_state: on (3->0) at 12005333628 (2000-01-03   
00:38:52.322241626 UTC)
Bad mode in prefetch abort handler detected
Internal error: Oops - bad mode: 0 [#1] PREEMPT
last sysfs file: /sys/devices/platform/pwm-backlight.0/backlight/pwm-  
backlight.0/brightness
Modules linked in:
CPU: 0    Not tainted  (2.6.35.3-01265-g8f56f17 #6)
PC is at 0x77802570
LR is at 0xafd0bf6c
pc : [<77802570>]    lr : [<afd0bf6c>]    psr: 200001d6
sp : ce0e7fb0  ip : 8151c780  fp : 00000001
r10: 00000000  r9 : 40a85000  r8 : 00000002
r7 : 4090ae64  r6 : 8151c890  r5 : 00000018  r4 : 40207000
r3 : 40a85000  r2 : 00000001  r1 : 60000010  r0 : 00000000
Flags: nzCv  IRQs off  FIQs off  Mode UK6_32  ISA ARM  Segment user
Control: 10c5387d  Table: 83668019  DAC: 00000015
Process Binder Thread # (pid: 2307, stack limit = 0xce0e62e8)
Stack: (0xce0e7fb0 to 0xce0e8000)
7fa0:                                     00000000 60000010 00000001    
40a85000
7fc0: 40207000 00000018 8151c890 4090ae64 00000002 40a85000 00000000  
00000001
7fe0: 8151c780 ce0e7fb0 afd0bf6c 77802570 200001d6 ffffffff ffc75a9a 
dfd4eed7
Code: bad PC value
---[ end trace d8447dd37d1d45d8 ]---
Kernel panic - not syncing: Fatal exception
[<c003e58c>] (unwind_backtrace+0x0/0xf0) from [<c04862f0>]     
(panic+0x6c/0xe0)
[<c04862f0>] (panic+0x6c/0xe0) from [<c003d420>] (die+0x2b4/0x304)
[<c003d420>] (die+0x2b4/0x304) from [<c003d4ac>] (bad_mode+0x3c/0x5c)
[<c003d4ac>] (bad_mode+0x3c/0x5c) from [<afd0bf6c>] (0xafd0bf6c)

我是否需要一些其他设置来将中止捕获到监控模式?最后,我将CSU设置为使I2C0 / IPU等外设安全并陷阱并模拟这些外设的中止。但我需要执行第一步,将中止指向监视处理函数。有人可以帮忙吗?

修改

首先让我尝试不带任何printf的预取中止处理程序(以减少错误的来源)。所以我们的目标是:abort进入监视器,监视器再次将控制权再次发送给NW,因为这个中止不感兴趣。

基本上,SCR中只有一位用于指定任何中止应该发生的事情。但我可能只对数据中止感兴趣(当某些特定外设访问时也是如此)。因此,第一步是在预取中止发生时将控制权交还给NW。

以下代码作为预取处理程序具有相同的输出:崩溃“检测到预取中止处理程序中的错误模式”。

.global tz_monitor
.align 5
tz_monitor:
    @ Monitor
    nop @ Reset      - not used by Monitor
    nop @ Undef      - not used by Monitor
    b   smc_handler
    b   pabort_handler @ Prefetch   - can by used by Monitor
    b   dabort_handler  @ Data abort - can by used by Monitor
    nop @ RESERVED
    nop @ IRQ        - can by used by Monitor
    nop @ FIQ        - can by used by Monitor

.global pabort_handler
pabort_handler:
    sub r14, r14, #4            @ on excpetion, processor stores     current pc to r14 or link register (lr), decrement by 4 for prefetch abort
    stmfd sp!, {r14}            @ save lr, to know where to return from exception
    mrs r14, spsr               @ on exception, processor stores current cpsr to spsr, read this to r14
    stmfd sp!, {r0-r12, r14}        @ save r14 and therefore spsr, also store general purpose registers r0-r12

    mrc p15, 0, r4, c1, c1, 0           @ Read Secure Configuration Register data
    bic r4, #NS_BIT                     @ clear NS bit
    mcr p15, 0, r4, c1, c1, 0           @ Write Secure Configuration Register data

    //bl monitor_prefetch @no printing for now

    mrc p15, 0, r4, c1, c1, 0           @ Read Secure Configuration Register data
    orr r4, #NS_BIT                     @ Set NS bit
    mcr p15, 0, r4, c1, c1, 0           @ Write Secure Configuration Register data

    ldmfd sp!,{r0-r12, r14}             @ restore from stack general purpose registers and read spsr value to r14 
    msr spsr, r14               @ restore spsr from r14
    ldmfd sp!, {pc}^            @ restore from stack lr-4 and set pc, the ^ denotes cpsr to be set with spsr

.global dabort_handler
dabort_handler:
    sub r14, r14, #8            @ on excpetion, processor stores current pc to r14 or link register (lr), decrement by 8 for data abort
    stmfd sp!, {r14}            @ save lr, to know where to return from exception
    mrs r14, spsr               @ on exception, processor stores current cpsr to spsr, read this to r14
    stmfd sp!, {r0-r12, r14}        @ save r14 and therefore spsr, also store general purpose registers r0-r12

    mrc p15, 0, r4, c1, c1, 0           @ Read Secure Configuration Register data
    bic r4, #NS_BIT                     @ clear NS bit
    mcr p15, 0, r4, c1, c1, 0           @ Write Secure Configuration Register data

    //bl monitor_prefetch  @no printing for now

    mrc p15, 0, r4, c1, c1, 0           @ Read Secure Configuration Register data
    orr r4, #NS_BIT                     @ Set NS bit
    mcr p15, 0, r4, c1, c1, 0           @ Write Secure Configuration Register data

    ldmfd sp!,{r0-r12, r14}             @ restore from stack general purpose registers and read spsr value to r14 
    msr spsr, r14               @ restore spsr from r14
    ldmfd sp!, {pc}^            @ restore from stack lr-4 and set pc, the ^ denotes cpsr to be set with spsr

0 个答案:

没有答案