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 を使用せずにプリフェッチ アボート ハンドラを試してみましょう (エラーの発生源を減らすため)。したがって、目標は、アボートがモニターに来ることです。このアボートは重要ではないため、モニターは再び制御を NW に戻します。
基本的に、SCR にはアボートの発生を指定するビットが 1 つしかありません。しかし、私が興味があるのはデータ アボートだけです (特定の周辺機器へのアクセスが発生した場合も同様です)。したがって、この最初のステップは、プリフェッチの中止が発生したときに制御を 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