我在 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
这些修改有一些变化,即内核在外部中止点崩溃。但是我没有在监视器处理程序中得到打印语句。启动 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 的预取中止处理程序(以减少错误的来源)。所以目标是:中止出现在监视器上,而监视器只是再次将控制权交还给 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